Question

I'm currently trying to build a Qt table by subclassing QTableView, QAbstractTableModel and QStyledItemDelegate to maintian some semblance of MVC archiectecture.

I'm using this simple example as a base to build on as I haven't gone near Qt table classes before:

http://qt-project.org/doc/qt-4.8/modelview.html

Anyway the table is mostly text columns but it also needs a single toggle button column and a single checkbox column.

I've noticed that the data method of the model can be used to implement a checkbox but I'm going to need a custom delegate for the button so I was going to use it for the checkbox also.

Anyway I'm unable to find any decent examples on the internet that create tables by using the QTableView object with a mixture of text, checkboxes and buttons. Can any of you good sirs point me in the right direction?

Was it helpful?

Solution 2

Based on the information Dmitry provided above I've implemented the following paint method in my delegate for rendering my button and checkbox. Obviously this needs an editorEvent() to do anything I can add this also if it proves useful.

void DDUTableDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
                            const QModelIndex& index) const
{
int col = index.column();

if (col == VIEW_COLUMN) {
    // Draw our checkbox indicator
    bool value = index.data(Qt::EditRole).toBool();
    QStyleOptionButton checkbox_indicator;

    // Set our button state to enabled
    checkbox_indicator.state |= QStyle::State_Enabled;
    checkbox_indicator.state |= (value) ? QStyle::State_On : QStyle::State_Off;

    // Get our deimensions
    checkbox_indicator.rect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &checkbox_indicator, NULL );

    // Position our indicator
    const int x = option.rect.center().x() - checkbox_indicator.rect.width() / 2;
    const int y = option.rect.center().y() - checkbox_indicator.rect.height() / 2;

    checkbox_indicator.rect.moveTo( x, y );

    if (option.state & QStyle::State_Selected) {
        painter->fillRect(option.rect, option.palette.highlight());       
    }

    QApplication::style()->drawControl( QStyle::CE_CheckBox, &checkbox_indicator, painter );
}
else if (col == TEST_COLUMN) {
     bool value = index.data(Qt::EditRole).toBool();

     QStyleOptionButton button;

     // Set our button to fill the entire cell contents
     button.rect = option.rect;

     // Set our button state to enabled
     button.state |= QStyle::State_Enabled;

     if (value) {
         button.state |= QStyle::State_Sunken;
         button.text = STOP_TEST;
     }
     else {
          button.text = START_TEST;
     }

     if (option.state & QStyle::State_Selected) {
        painter->fillRect(option.rect, option.palette.highlight());         
     }

     QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter);

}   
}

OTHER TIPS

You don't need a custom delegate for having checkbox and toggle button in your tableview. You can simply make your item checkable and set it to your model like:

QStandardItem *item = new QStandardItem( true );
item->setCheckable(true);
item->setCheckState(Qt::Unchecked);

QStandardItemModel * model = new QStandardItemModel( 0, 2 );
model->setRowCount(1);
model->setItem(0, 0, item);

For a toggle button you can do like:

QPushButton * but = new QPushButton(this);
but->setCheckable(true);
but->setText("Toggle");

ui->tableView->setIndexWidget(model->item(0,1)->index(),but);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top