Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QComboBox and QSqlRelationalDelegate doesn't allow to choose element with index over 255
Forum Updated to NodeBB v4.3 + New Features

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

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 452 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    BrokenVoodooDoll
    wrote on last edited by
    #1

    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);
    }
    
    
    JonBJ 1 Reply Last reply
    0
    • B BrokenVoodooDoll

      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);
      }
      
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @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?

      1 Reply Last reply
      2
      • B Offline
        B Offline
        BrokenVoodooDoll
        wrote on last edited by
        #3

        Great! That works! Thank you!

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved