2

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?

RAM
  • 2,257
  • 2
  • 19
  • 41
kh25
  • 1,238
  • 1
  • 15
  • 33
  • I already stated above I'm creating a delegate. Provide some examples or something new to the thread or don't answer. Creating a delegate and overriding the cell contents is a given. Otherwise I'd use the default delegate. Examples of doing it with a button or a checkbox is what's required. – kh25 Apr 04 '14 at 14:26
  • So you want us to write a code for you? Without any attempts from your side? – Dmitry Sazonov Apr 04 '14 at 14:33
  • 1
    Use same code, but draw a button instead of checkbox: http://stackoverflow.com/a/16301316/1035613 – Dmitry Sazonov Apr 04 '14 at 14:36
  • No I was expecting possibly a link to a page that had an example of a delegate using it's paint() method to create a toggle button or a checkbox as indicated in the last paragraph of my statement. Considering the paint method for a button or a checkbox should just either work or not work It would be unlikely if I had an example that I'd need to ask anyone to point me in the direction of further examples. Anyway clearly this is something either people have done before (and therefore will know how to do it or will have an example of how to do it). – kh25 Apr 04 '14 at 14:47
  • Thanks very much that's all I required. – kh25 Apr 04 '14 at 14:54

2 Answers2

4

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);
Nejat
  • 31,784
  • 12
  • 106
  • 138
1

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);

}   
}
kh25
  • 1,238
  • 1
  • 15
  • 33
  • BTW, instead of checking for column number inside the delegate you could use `setItemDelegateForColumn` convenience method. – Vader B Nov 28 '18 at 13:17