Sorting QSortFilterProxyModel based on two sorting roles?

In my project, I have a model displayed in a tree. I used QSortFilterProxyModel to sort the model based on the ID set in Qt :: UserRole + 1. This divides my list by "type" (as you can tell from the icons used):

enter image description here

However, I also want each "type" to be sorted alphabetically. I first tried to sort things alphabetically by FIRST and THEN, sorting by type to see if it would change the order of things, but it stays the same. Is there a way to tell my program to sort with two sorting roles and determine which one "comes first?"

proxy->setSortRole(Qt::DisplayRole);
proxy->setSortRole(Qt::UserRole+1);

      

+3


source to share


3 answers


Since my duplicate urls have been removed, here is a working example straight from the official example after some minor adjustments:

class MySortFilterProxyModel Q_DECL_FINAL : public QSortFilterProxyModel
{
    Q_OBJECT

public:
    MySortFilterProxyModel(QObject *parent)
        : QSortFilterProxyModel(parent)
    {
    }

protected:
    bool lessThan(const QModelIndex &left, const QModelIndex &right) const Q_DECL_OVERRIDE
    {
        QVariant leftData = sourceModel()->data(left);
        QVariant rightData = sourceModel()->data(right);
        // Do custom logic in here, e.g.:
        return QString::localeAwareCompare(leftData.toString(), rightData.toString()) < 0;
    }
};

      



This custom class will then be used normally instead of the original as a replacement. That's all!

+1


source


All I had to do was create a proxy model of another proxy model. The first proxy ordered things alphabetically, the second proxy ordered the first proxy UserRole + 1.

QSortFilterProxyModel* proxy = new QSortFilterProxyModel(ui->treeNBT);
proxy->setSourceModel(model);
proxy->setDynamicSortFilter(false);
proxy->sort(0, Qt::AscendingOrder);
proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
proxy->setSortRole(Qt::DisplayRole);
QSortFilterProxyModel* proxy2 = new QSortFilterProxyModel(ui->treeNBT);
proxy2->setSourceModel(proxy);
proxy2->setDynamicSortFilter(false);
proxy2->sort(0, Qt::AscendingOrder);
proxy2->setSortRole(Qt::UserRole+1);
ui->treeNBT->setModel(proxy2);

      



Much easier than writing custom sorting logic in an overridden class. There is no noticeable performance improvement, so this is what I am using.

Edit: changed my answer ... looking back at my old questions and this is not the best way to do it. Re-executing the class was the best (and obvious) way. oops.

+4


source


You need to subclass the proxy and implement your own lessThan()

.

QSortFilterProxyModel uses a virtual lessThan

method to determine the ordering between model indexes. Only the standard implementation lessThan

matches the role that is established setSortRole

. You can override it to provide custom sorting behavior, in which case it is setSortRole

deprecated.

The official documentation has a section on custom sorting and sample code: http://doc.qt.io/qt-5/qsortfilterproxymodel.html#details

-1


source







All Articles