问题描述
我正在尝试实现一个可在多个列上排序的表.Qt 的 QSortFilterProxyModel 仅支持对一列进行排序(至少在 Qt 4.6.2 中).
I am trying to implement a table that is sortable on more than one column. Qt's QSortFilterProxyModel only supports sorting on one column (at least in Qt 4.6.2).
我在 github 上找到了 dimkanovikov 的此解决方案,但它缺少对添加行的动态更新.我的意思是,模型发生了变化,并且 beginInsertRows()、beginRemoveRows()、它们对应的 end..-methods 和 dataChanged() 信号被发出.理想情况下,我只想更新这些行,但模型至少应该对此类更改做出反应.
I've found this solution by dimkanovikov on github, but it lacks dynamic updating on added rows. What I mean by this, is that the model is changed and the beginInsertRows(), beginRemoveRows(), their corresponding end..-methods and the dataChanged() signals are emitted. Ideally I would like to only these rows to be updated, but the model should at least react to such changes.
Qt 网站上还有另一个常见问题解答项目,可以对 QTableWidget 进行排序,但它也缺乏动态更新.
There's another FAQ item on Qt's site that sorts a QTableWidget, but it lacks dynamic updating, too.
我是 Qt 的新手,我想得到一些关于我应该如何处理的建议.
I am new to Qt and I'd like to get some pointers on how I should go about this.
推荐答案
有一个稍微不雅的解决方案,它总是用于对多列进行排序.
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.
这篇关于QSortFilterProxyModel 对多列进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!