Qt Using Custom QItemDelegate for QTableView

First, you should have a description of your model columns:

enum Columns
{
    COL_NAME,
    COL_TIME,
    COL_STATUS
}

Your delegate should only work for the last column.

Here is an example of how you can populate your model:

for (int i = 0; i < 5; ++i)
{
    QStandardItem *itemName = new QStandardItem(QString("name %1").arg(i));
    QStandardItem *itemTime = new QStandardItem(QString("time %1").arg(i));

    QString status;
    if (i % 2 == 0)
    {
        status = "Enabled";
    }
    else
    {
        status = "Disabled";
    }

    QStandardItem *itemStatus = new QStandardItem(status);

    QList<QStandardItem*> row;
    row << itemName << itemTime << itemStatus;

    model->appendRow(row);
}

As I said, your delegate should only work for the last column. So all methods you have reimplemented should have a column check like this:

QWidget* QComboBoxItemDelegate::createEditor(QWidget *parent, 
                            const QStyleOptionViewItem &option, 
                            const QModelIndex &index) 
{
    if (index.column() == COL_STATUS)
    {
        QStringList values;
        values << "Enabled" << "Disabled";

        QComboBox* comboBox = new QComboBox(parent);
        comboBox->addItems(values);
        return comboBox;
    }
    else
    {
        return QItemDelegate::createEditor(parent, option, index);
    }
}

You should add this check to the other methods: if the current column is not the status column, the base class (QItemDelegate) implementation should be used.

Then you set your delegate to your view:

ui->tableView->setItemDelegate(new ComboBoxDelegate);

If you do everything right, a combo Box will appear in the last column if you try to edit its values.


Even more simply; I found QTableView::setItemDelegateForColumn() to work admirably for a column. For example, in your MainWindow, you could make a member:

QComboBoxItemDelegate dgtComboDelegate;

Then, in your ctor, or init(), you could have

ui->tableView->setItemDelegateForColumn(2, dgtComboDelegate);

If you wanted that to happen for a single cell, that's when you need to test on the index.column() and index.row().

You know, you don't have to create a QTableView to do this either. E.g., see the ?:

Qt - Centering a checkbox in a QTable

The OP doesn't give the declaration for a table widget or view; but it does have the QTableView tag. It should work equally well for either.

In the former case, you can do ui->tableWidget->setItemDelegateForColumn(2, dgtComboDelegate); and never have to make your own model. Just use setData() on the items you create (or even later, for that matter,) to initialize their values.