Solved QComboBox and QSqlRelationalDelegate doesn't allow to choose element with index over 255
-
I work with
QSqlRelationalTableModel
andQSortFilterProxyModel
. I made a custom delegate to work with the relational table model through the proxy model. But my relation tables contain a lot of records (more than 256), therefore combo boxes of the delegate contain a lot of rows. When I try to select an item from a combo box that has an index exceeding 256, the current index of the combo box just doesn't change. But if the index's row is lower than 256, it works. I tried it either withQSqlRelationalDelegate
or with my custom "SqlRelationalProxyDelegate", nothing works in a proper way. I even tried to force the combo box's model to be fully fetched. I used a debugger and found out thatsetEditorData
andsetModelData
methods of the delegate even aren't called when I select an item with a row value more than 256.
It worth mentioning that if I populate a combo box withQSqlQueryModel
with the same tables, it works correctly. But I want to use delegate but not this crutch.
My code:
sqlrelationalproxydelegate.h#include <QSqlRelationalDelegate> class SqlRelationalProxyDelegate : public QSqlRelationalDelegate { Q_OBJECT public: SqlRelationalProxyDelegate(QObject* parent = nullptr); QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; void setEditorData(QWidget* editor, const QModelIndex& index) const override; };
sqlrelationalproxydelegate.cpp
#include "sqlrelationalproxydelegate.h" #include <QSortFilterProxyModel> #include <QDebug> SqlRelationalProxyDelegate::SqlRelationalProxyDelegate(QObject* parent) : QSqlRelationalDelegate(parent) {} QWidget *SqlRelationalProxyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { // const QSortFilterProxyModel* proxyModel = qobject_cast<const QSortFilterProxyModel*>(index.model()); // Q_ASSERT(proxyModel); // const QSqlRelationalTableModel* sqlModel = qobject_cast<const QSqlRelationalTableModel*>(proxyModel->sourceModel()); // Q_ASSERT(sqlModel); // QSqlTableModel* childModel = sqlModel->relationModel(index.column()); // Q_ASSERT(childModel); // while(childModel->canFetchMore()) { // childModel->fetchMore(); // } // QModelIndex baseIndex = proxyModel->mapToSource(index); // return QSqlRelationalDelegate::createEditor(parent, option, baseIndex); const QSortFilterProxyModel* proxyModel = qobject_cast<const QSortFilterProxyModel*>(index.model()); Q_ASSERT(proxyModel); QModelIndex baseIndex = proxyModel->mapToSource(index); QComboBox* combo = qobject_cast<QComboBox*>(QSqlRelationalDelegate::createEditor(parent, option, baseIndex)); while (combo->model()->canFetchMore(QModelIndex())) { combo->model()->fetchMore(QModelIndex()); } return combo; } void SqlRelationalProxyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { const QSortFilterProxyModel* proxyModel = qobject_cast<const QSortFilterProxyModel*>(index.model()); Q_ASSERT(proxyModel); QModelIndex baseIndex = proxyModel->mapToSource(index); QSqlRelationalDelegate::setEditorData(editor, baseIndex); } void SqlRelationalProxyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QSortFilterProxyModel* proxyModel = qobject_cast<QSortFilterProxyModel*>(model); Q_ASSERT(proxyModel); QSqlRelationalTableModel* baseModel = qobject_cast<QSqlRelationalTableModel*>(proxyModel->sourceModel()); Q_ASSERT(baseModel); QModelIndex baseIndex = proxyModel->mapToSource(index); QSqlRelationalDelegate::setModelData(editor, baseModel, baseIndex); }
-
@BrokenVoodooDoll said in QComboBox and QSqlRelationalDelegate doesn't allow to choose element with index over 255:
I even tried to force the combo box's model to be fully fetched.
Just a general guess for the line to pursue. Qt fetches hard-coded 256 rows. I think you are right and you need to force it to fetch all rows before you have any chance.
To see it it makes any difference, can you pre-fetch the whole model before
createEditor()
gets called, instead of inside it? -
Great! That works! Thank you!