Qt Using Custom QItemDelegate for QTableView

我怕爱的太早我们不能终老 提交于 2019-11-29 21:57:34
hank

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.

So I figured out that I did not override the correct function prototypes..! I forgot that they had const in the prototype meaning that I was not overriding any functions so it was using the default ones. Here are the correct virtual functions that have to be re-implemented: http://qt-project.org/doc/qt-5.0/qtwidgets/qitemdelegate.html

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 latter 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!