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. Sort QSqlRelation in a QSqlTable model
Forum Updated to NodeBB v4.3 + New Features

Sort QSqlRelation in a QSqlTable model

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 490 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.
  • eortegaE Offline
    eortegaE Offline
    eortega
    wrote on last edited by
    #1

    Hi all,

    I'm trying to have the values comming from a QSqlRelation sorted alfabetically inside the combo box but I cannot find the way. I was reading the documentation of QSqlRelation but I think that it cannot be done from there. Any hint of how can do the sorting of th combobox given by the QSqlRelation?

    Thanks!

    1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      QComboBox has a property to speficy the insertion order: https://doc.qt.io/qt-5/qcombobox.html#InsertPolicy-enum

      If this does not work place a QSortFilterProxyModel between the QSqlRelation and the QComboBox.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      3
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #3

        How are you setting the values in the combobox?
        It should be straightforward using a QSortFilterProxyModel subclass

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        3
        • eortegaE Offline
          eortegaE Offline
          eortega
          wrote on last edited by
          #4

          Thanks both for the replies.

          In fact, the combo box is placed automatically by the QSqlRelation. The values are automatically filled by the content of the table specified in the relation, so I have no way to modify the QComboBox...

          model->setRelation(2, QSqlRelation("city", "id", "name"));
          

          In the example (https://doc.qt.io/qt-5/qtsql-relationaltablemodel-example.html) if you click on a cell in Country or City columns you get the values of the Country or the City sorted by id, not by name, and I cannot find the way to have sorted them by name.

          1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by VRonin
            #5

            Yep, as I mentioned it's easy to achieve with a simple QSortFilterProxyModel.

            class SortedRelationalDelegate : public QSqlRelationalDelegate{
                Q_OBJECT
                Q_DISABLE_COPY(SortedRelationalDelegate)
            public:
                explicit SortedRelationalDelegate(QObject* parent = nullptr) :QSqlRelationalDelegate(parent){}
                QWidget *createEditor(QWidget *aParent, const QStyleOptionViewItem &option, const QModelIndex &index) const override{
                    QWidget* const unsortedWidget = QSqlRelationalDelegate::createEditor(aParent,option,index);
                    QComboBox* const combo = qobject_cast<QComboBox*>(unsortedWidget);
                    Q_ASSERT(combo);
                    QSortFilterProxyModel* const comboSorter = new QSortFilterProxyModel(combo);
                    comboSorter->setSourceModel(combo->model());
                    comboSorter->sort(combo->modelColumn());
                    combo->setModel(comboSorter);
                    return combo;
                }
                void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override{
                    QComboBox* const combo = qobject_cast<QComboBox*>(editor);
                    Q_ASSERT(combo);
                    QSortFilterProxyModel* const sorter = qobject_cast<QSortFilterProxyModel*>(combo->model());
                    Q_ASSERT(sorter);
                    const int mappedIndex = sorter->mapToSource(sorter->index(combo->currentIndex(),combo->modelColumn())).row();
                    combo->setModel(sorter->sourceModel());
                    combo->setCurrentIndex(mappedIndex);
                    QSqlRelationalDelegate::setModelData(combo,model,index);
                }
            };
            
                
            

            To use it, call setItemDelegateForColumn on the view for the column that should display the combo

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            eortegaE 1 Reply Last reply
            1
            • VRoninV VRonin

              Yep, as I mentioned it's easy to achieve with a simple QSortFilterProxyModel.

              class SortedRelationalDelegate : public QSqlRelationalDelegate{
                  Q_OBJECT
                  Q_DISABLE_COPY(SortedRelationalDelegate)
              public:
                  explicit SortedRelationalDelegate(QObject* parent = nullptr) :QSqlRelationalDelegate(parent){}
                  QWidget *createEditor(QWidget *aParent, const QStyleOptionViewItem &option, const QModelIndex &index) const override{
                      QWidget* const unsortedWidget = QSqlRelationalDelegate::createEditor(aParent,option,index);
                      QComboBox* const combo = qobject_cast<QComboBox*>(unsortedWidget);
                      Q_ASSERT(combo);
                      QSortFilterProxyModel* const comboSorter = new QSortFilterProxyModel(combo);
                      comboSorter->setSourceModel(combo->model());
                      comboSorter->sort(combo->modelColumn());
                      combo->setModel(comboSorter);
                      return combo;
                  }
                  void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override{
                      QComboBox* const combo = qobject_cast<QComboBox*>(editor);
                      Q_ASSERT(combo);
                      QSortFilterProxyModel* const sorter = qobject_cast<QSortFilterProxyModel*>(combo->model());
                      Q_ASSERT(sorter);
                      const int mappedIndex = sorter->mapToSource(sorter->index(combo->currentIndex(),combo->modelColumn())).row();
                      combo->setModel(sorter->sourceModel());
                      combo->setCurrentIndex(mappedIndex);
                      QSqlRelationalDelegate::setModelData(combo,model,index);
                  }
              };
              
                  
              

              To use it, call setItemDelegateForColumn on the view for the column that should display the combo

              eortegaE Offline
              eortegaE Offline
              eortega
              wrote on last edited by
              #6

              @VRonin Thank you! I'm going to do it ASAP.

              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