Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QComboBox and QSqlRelationalDelegate doesn't allow to choose element with index over 255



  • I work with QSqlRelationalTableModel and QSortFilterProxyModel. 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 with QSqlRelationalDelegate 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 that setEditorData and setModelData 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 with QSqlQueryModel 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!


Log in to reply