且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

QSortFilterProxyModel 对多列进行排序

更新时间:2023-01-29 18:35:15

有一个稍微不雅的解决方案,它总是用于对多列进行排序.

There's one slightly inelegant solution, that is always used to sort multiple columns.

您必须继承 QSortFilterProxyModel 并重新实现 bool lessThan(const QModelIndex &rLeft, const QModelIndex &rRight) const.检查所有列,而不是仅在两个给定索引之间进行比较:

You have to subclass QSortFilterProxyModel and reimplement bool lessThan(const QModelIndex &rLeft, const QModelIndex &rRight) const. Instead of only comparing between the two given indices, check all the columns:

int const left_row  = rLeft.row();
int const right_row = rRight.row();

int const num_columns = sourceModel()->columnCount();
for(int compared_column = rLeft.column(); compared_column<num_columns; ++compared_column) {
    QModelIndex const left_idx = sourceModel()->index(left_row, compared_column, QModelIndex());
    QModelIndex const right_idx = sourceModel()->index(right_row, compared_column, QModelIndex());

    QString const leftData = sourceModel()->data(left_idx).toString();
    QString const rightData = sourceModel()->data(right_idx).toString();

    int const compare = QString::localeAwareCompare(leftData, rightData);
    if(compare!=0) {
        return compare<0;
    }
}

return false;

然后您可以在您的 QSortFilterProxyModel 子类上调用 sort(0) ,它将对所有列进行排序.如果您希望在模型数据更改时动态重新排序已排序的行,也不要忘记调用 setDynamicSortFilter(true).

Then you can call sort(0) on your QSortFilterProxyModel subclass and it will sort all the columns. Also don't forget to call setDynamicSortFilter(true) when you want the sorted rows to be dynamically resorted when the model data changes.

要支持按升序或降序对任意列进行排序,您必须将此信息保存在 QList 中,并在调用 lessThan 时进行相应比较.在列表中,您将按优先级顺序排列列,并以相同的顺序进行比较.您还应该以某种预定义的顺序对其他非活动"列进行排序,否则默认情况下它们不会被排序.

To support sorting on arbitrary columns in ascending or descending order, you would have to keep this info in a QList and compare accordingly when lessThan is called. In the list you would have the columns in order of their priority and do the comparisons in the same order. You should also sort the other "inactive" columns in some predefined order, otherwise they will not be sorted by default.