首页 > 解决方案 > 即使委托仅添加到 QTableView,QListView 项目也显示委托编辑器

问题描述

我有 aQListView和 aQTableView都一样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();
}

标签: c++qtqt5qspinboxqstyleditemdelegate

解决方案


问题其实很简单,如果model中保存的数据是数字,那么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);
}

推荐阅读