QStyledItemDelegate::createEditor() not getting called
-
The problem seems to be the QAIV::buddy() function (or better the reimplementation in QSFPM). Simply replace the implementation by
QModelIndex buddy(const QModelIndex &index) const override { return index; }
and the editing works as expected.
@Christian-Ehrlicher
Yay, it works! You are a hero :)https://doc.qt.io/qt-5/qabstractitemmodel.html#buddy was the missing link:
Returns a model index for the buddy of the item represented by index. When the user wants to edit an item, the view will call this function to check whether another item in the model should be edited instead. Then, the view will construct a delegate using the model index returned by the buddy item.
The default implementation of this function has each item as its own buddy.
The relevance, of course, is "When the user wants to edit an item", but I hadn't noticed that among all the possible functions needed to override.
-
For the sake of completeness, I present as the solution a complete, standalone, working code for this situation. For simplicity, I have removed any use of a
QStyledItemDelegate
forQTreeView::setItemDelegate()
as this is not required.It shows the minimal needed to allow for a
QAbstractProxyModel
, derived fromQIdentityProxyModel
, where you want to combine data from an underlying genuine source model with additional data held in, or external to, the proxy model layer.I am marking this as the solution. Thanks to @Christian-Ehrlicher for all his hard work/solutions!
#include <QApplication> #include <QDebug> #include <QIdentityProxyModel> #include <QStandardItemModel> #include <QTreeView> class MyProxyModel : public QIdentityProxyModel { int proxyData[5] = { 5, 6, 7, 8, 9 }; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_ASSERT(!parent.isValid()); return 5; } virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override { Q_ASSERT(!parent.isValid()); return 2; } virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override { if (role == Qt::DisplayRole) { if (orientation == Qt::Horizontal) return QString("Column #%1 (%2)").arg(section).arg(section == 0 ? "source model" : "proxy model"); } return QIdentityProxyModel::headerData(section, orientation, role); } virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { if (!index.isValid()) return QVariant(); if (index.column() == 1) { if (role == Qt::DisplayRole || role == Qt::EditRole) return proxyData[index.row()]; return QVariant(); } return QIdentityProxyModel::data(index, role); } virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override { if (index.column() == 1) { if (role == Qt::DisplayRole || role == Qt::EditRole) { proxyData[index.row()] = value.toInt(); return true; } return false; } return QIdentityProxyModel::setData(index, value, role); } virtual Qt::ItemFlags flags(const QModelIndex &index) const override { if (!index.isValid()) return Qt::NoItemFlags; if (index.column() == 1) return (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); return QIdentityProxyModel::flags(index); } virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override { if (!sourceIndex.isValid()) return QModelIndex(); Q_ASSERT(sourceIndex.column() == 0); return createIndex(sourceIndex.row(), 0); } virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const override { if (!proxyIndex.isValid()) return QModelIndex(); if (proxyIndex.column() == 1) return QModelIndex(); Q_ASSERT(proxyIndex.column() == 0); return sourceModel()->index(proxyIndex.row(), 0); } virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override { Q_ASSERT(!parent.isValid()); QModelIndex proxyIndex = createIndex(row, column); if (proxyIndex.column() == 1) return proxyIndex; return mapFromSource(mapToSource(proxyIndex)); } virtual QModelIndex sibling(int row, int column, const QModelIndex &idx) const override { if (!idx.isValid()) return QModelIndex(); Q_ASSERT(!idx.parent().isValid()); if (column == 1) return index(row, column); return mapFromSource(sourceModel()->sibling(row, column, mapToSource(idx))); } virtual QModelIndex buddy(const QModelIndex &index) const override { return index; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QStandardItemModel *model; MyProxyModel *proxy; QTreeView *tv; model = new QStandardItemModel(5, 1); for (int row = 0; row < model->rowCount(); row++) model->setData(model->index(row, 0), row); proxy = new MyProxyModel; proxy->setSourceModel(model); tv = new QTreeView; tv->setModel(proxy); tv->show(); return a.exec(); }