Sort QSqlRelation in a QSqlTable model
-
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!
-
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.
-
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.
-
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