QSortFilterProxyModel基于两个排序角色排序?

时间:2014-12-26 08:09:09

标签: c++ qt qsortfilterproxymodel

在我的项目中,我在树视图中显示了一个模型。我使用QSortFilterProxyModel根据Qt :: UserRole + 1中设置的ID对模型进行排序。这将我的列表除以“类型”(正如您所使用的图标所示):

enter image description here

但是我也希望每个“类型”按字母顺序排序。我最初尝试按字母顺序对事物进行排序,然后按类型对其进行排序以查看它是否会重新排列正常工作的东西,但它保持不变。有没有办法告诉我的程序用两个排序角色排序并确定哪一个“先行?”

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

3 个答案:

答案 0 :(得分:4)

我需要做的就是创建另一个代理模型的代理模型。第一个代理按字母顺序排序,第二个代理按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);

比在重新实现的类中编写自定义排序逻辑简单得多。没有明显的性能影响,所以这就是我正在使用的。

编辑:改变了我的回答......回顾我以前的问题,这不是最好的解决方法。重新实现课程是更好(和明显)的方式。糟糕。

答案 1 :(得分:1)

您需要子代理代理并实现自己的lessThan()

QSortFilterProxyModel使用虚拟lessThan方法来确定模型索引之间的排序。只有lessThan的默认实现尊重setSortRole设置的角色。您可以覆盖它以提供自定义排序行为,在这种情况下setSortRole已过时。

官方文档中有一节关于自定义排序以及代码示例:http://doc.qt.io/qt-5/qsortfilterproxymodel.html#details

答案 2 :(得分:1)

由于我的重复网址已被修改,因此经过一些小的调整后,这里是工作示例right from the official example

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;
    }
};

然后,这个自定义类将正常用于代替原始类作为替代品。就是这样!