2

我正在尝试实现一个可在多个列上排序的表。Qt 的 QSortFilterProxyModel 只支持在一列上排序(至少在 Qt 4.6.2 中)。

我在 github 上通过 dimkanovikov找到了这个解决方案,但它缺乏对添加行的动态更新。我的意思是,模型发生了变化,beginInsertRows()、beginRemoveRows()、它们对应的 end..-methods 和 dataChanged() 信号被发出。理想情况下,我只想更新这些行,但模型至少应该对这些变化做出反应。

Qt 网站上有另一个常见问题解答项目,它对 QTableWidget 进行排序,但它也缺乏动态更新。

我是 Qt 的新手,我想获得一些关于我应该如何去做的指示。

4

2 回答 2

7

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

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

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;

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

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

于 2012-06-27T08:24:28.937 回答
7

您可以将 的排序角色设置为与QSortFilterProxyModel默认值不同的内容。然后,在您的模型方法中,如果使用角色调用它,则返回正确的排序键,例如通过连接所涉及列的字符串。Qt::DisplayRolesetSortRole(Qt::UserRole)data()Qt::UserRole

于 2012-08-06T21:01:40.260 回答