QListView 项目也显示委托编辑器,即使委托仅添加到 QTableView

QListView items also showing the delegate editor even though the delegate is only added to the QTableView

我有一个 QListView 和一个 QTableView 都有相同的 QStandardItemModel。我已将自定义委托人添加到 QTableView。现在,当我转到 QTableView 并双击一个项目时,我会看到委托编辑器小部件,现在如果我转到 QListView 并双击同一项目,我会在那里看到委托编辑器小部件出色地。需要注意的一点是,我只看到 QListView 中已在 QTableView 中双击的那些项目的编辑器小部件。这里发生了什么?为什么 QListView 项也显示委托编辑器小部件,即使委托仅添加到 QTableView

作为参考,我有以下代码:

#include <QtWidgets/QApplication>
#include <QtGui>
#include <QCombobox>
#include <QListview>
#include <QTableview>
#include <QLayout>
#include <QColor>
#include <QStyledItemDelegate>
#include <QSpinbox>

class SpinBoxDeligate : public QStyledItemDelegate {
public:
    QWidget * createEditor(QWidget *parent,
        const QStyleOptionViewItem &option,
        const QModelIndex &index) const override {
        auto w = new QSpinBox(parent);
        w->setFrame(false);
        w->setMinimum(0);
        w->setMaximum(100);
        return w;
    }

    void setEditorData(QWidget *editor, const QModelIndex &index) const override {
        static_cast<QSpinBox*>(editor)->setValue(index.data(Qt::EditRole).toInt());
    }

    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override {
        model->setData(index, static_cast<QSpinBox*>(editor)->value(), Qt::EditRole);
    }
};


int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    QStandardItemModel model(3, 1);

    for (int r = 0; r < 3; ++r)
    {
        auto text = QString("%0").arg(r);
        QStandardItem* item = new QStandardItem(text);

        item->setFlags(Qt::ItemIsUserCheckable
            | Qt::ItemIsEnabled
            | Qt::ItemIsEditable
        );
        item->setData(Qt::Unchecked, Qt::CheckStateRole);
        item->setData(text, Qt::ToolTipRole);
        item->setData(QSize(100, 30), Qt::SizeHintRole);
        item->setData(QIcon(":/QtMVC/Desert.jpg"), Qt::DecorationRole);
        model.setItem(r, 0, item);
    }

    QComboBox* combo = new QComboBox();
    combo->setModel(&model);

    QListView* list = new QListView();
    list->setModel(&model);

    QTableView* table = new QTableView();
    table->setModel(&model);
    table->setItemDelegate(new SpinBoxDeligate());

    QWidget w;
    QVBoxLayout* containerLayout = new QVBoxLayout();
    w.setLayout(containerLayout);
    containerLayout->addWidget(combo);
    containerLayout->addWidget(list);
    containerLayout->addWidget(table);
    w.show();

    return app.exec();
}

问题其实很简单,如果模型中保存的数据是数字,delegate默认是QSpinBox,即你看到的delegate是QListView,不是SpinBoxDeligate,而是默认的delegate。

为什么不留号会生成? 这是因为 SpinBoxDeligate 将数据保存为数字。

所以解决方法是将SpinBoxDeligate获取的数据保存为文本:

void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override {
    model->setData(index, static_cast<QSpinBox*>(editor)->text(), Qt::EditRole);
}