How to insert QPushButton into TableView?
Asked Answered
P

3

5

I am implementing QAbstractTableModel and I would like to insert a QPushButton in the last column of each row. When users click on this button, a new window is shown with more information about this row.

Do you have any idea how to insert the button? I know about delegating system but all examples are only about "how to edit color with the combo box"...

Protectionism answered 4/5, 2010 at 15:57 Comment(0)
M
4

The model-view architecture isn't made to insert widgets into different cells, but you can draw the push button within the cell.

The differences are:

  1. It will only be a drawing of a pushbutton
  2. Without extra work (perhaps quite a bit of extra work) the button won't be highlighted on mouseover
  3. In consequence of #1 above, you can't use signals and slots

That said, here's how to do it:

Subclass QAbstractItemDelegate (or QStyledItemDelegate) and implement the paint() method. To draw the pushbutton control (or any other control for that matter) you'll need to use a style or the QStylePainter::drawControl() method:

class PushButtonDelegate : public QAbstractItemDelegate
{
    // TODO: handle public, private, etc.
    QAbstractItemView *view;

    public PushButtonDelegate(QAbstractItemView* view)
    {
        this->view = view;
    }

    void PushButtonDelegate::paint(
        QPainter* painter,
        const QStyleOptionViewItem & option,
        const QModelIndex & index
        ) const 
    {
        // assuming this delegate is only registered for the correct column/row
        QStylePainter stylePainter(view);
        // OR: stylePainter(painter->device)

        stylePainter->drawControl(QStyle::CE_PushButton, option);
        // OR: view->style()->drawControl(QStyle::CE_PushButton, option, painter, view);
        // OR: QApplication::style()->drawControl(/* params as above */);
    }
}

Since the delegate keeps you within the model-view realm, use the views signals about selection and edits to popup your information window.

Manvell answered 4/5, 2010 at 16:40 Comment(3)
Voted this up but wanted to add: You could get the button to actually be a button rather than a drawing of a button, but it's probably not worth it because of the overhead. You'd have to create a custom editor and have the cell go into edit mode on mouse over.Tracheid
Interesting thought. It may be possible but I'm not sure exactly how I would implement that. The setEditorData() calls happen in the bowels of QAbstractItemView so it looks like it would be a LOT of work, assuming it's possible. On a related note, it's actually fairly easy to hook into the hover and do a repaint to show a visible hint.Manvell
What will change in your code if one would want to draw a widget, instead of just a button? What does that QStyle::CE_PushButton do?Yasmin
D
11

You can use

QPushButton* viewButton = new QPushButton("View");    
tableView->setIndexWidget(model->index(counter,2), viewButton);
Deaver answered 15/5, 2014 at 17:57 Comment(0)
M
4

The model-view architecture isn't made to insert widgets into different cells, but you can draw the push button within the cell.

The differences are:

  1. It will only be a drawing of a pushbutton
  2. Without extra work (perhaps quite a bit of extra work) the button won't be highlighted on mouseover
  3. In consequence of #1 above, you can't use signals and slots

That said, here's how to do it:

Subclass QAbstractItemDelegate (or QStyledItemDelegate) and implement the paint() method. To draw the pushbutton control (or any other control for that matter) you'll need to use a style or the QStylePainter::drawControl() method:

class PushButtonDelegate : public QAbstractItemDelegate
{
    // TODO: handle public, private, etc.
    QAbstractItemView *view;

    public PushButtonDelegate(QAbstractItemView* view)
    {
        this->view = view;
    }

    void PushButtonDelegate::paint(
        QPainter* painter,
        const QStyleOptionViewItem & option,
        const QModelIndex & index
        ) const 
    {
        // assuming this delegate is only registered for the correct column/row
        QStylePainter stylePainter(view);
        // OR: stylePainter(painter->device)

        stylePainter->drawControl(QStyle::CE_PushButton, option);
        // OR: view->style()->drawControl(QStyle::CE_PushButton, option, painter, view);
        // OR: QApplication::style()->drawControl(/* params as above */);
    }
}

Since the delegate keeps you within the model-view realm, use the views signals about selection and edits to popup your information window.

Manvell answered 4/5, 2010 at 16:40 Comment(3)
Voted this up but wanted to add: You could get the button to actually be a button rather than a drawing of a button, but it's probably not worth it because of the overhead. You'd have to create a custom editor and have the cell go into edit mode on mouse over.Tracheid
Interesting thought. It may be possible but I'm not sure exactly how I would implement that. The setEditorData() calls happen in the bowels of QAbstractItemView so it looks like it would be a LOT of work, assuming it's possible. On a related note, it's actually fairly easy to hook into the hover and do a repaint to show a visible hint.Manvell
What will change in your code if one would want to draw a widget, instead of just a button? What does that QStyle::CE_PushButton do?Yasmin
Q
0

You can use setCellWidget(row,column,QWidget*) to set a widget in a specific cell.

Quinque answered 20/10, 2011 at 13:55 Comment(1)
That appears to be a method of QTableWidget not QTableView.Reface

© 2022 - 2024 — McMap. All rights reserved.