模型排序时更新 QTableView/QHeaderView 中的排序指示符

Posted

技术标签:

【中文标题】模型排序时更新 QTableView/QHeaderView 中的排序指示符【英文标题】:Updating sort-order indicator in QTableView/QHeaderView when model is sorted 【发布时间】:2014-06-02 11:46:21 【问题描述】:

我想知道如何确保在对模型执行编程排序时更新QTableView 水平标题中的排序指示符。

问题来了:

QStandardItemModel model(3,1);
QTableView view;
view.setModel( &model );

// Populate the model ensuring it is not in a sorted order
for( int row = 0; row < model.rowCount(); ++row )

    model.setItem( row , 0 ,
                   new QStandardItem(QString::number((row+1)%model.rowCount())));


view.setSortingEnabled( true );
// At this point everything is consistent since enabling the sorting
// triggers a sort that matches the indicator in the horizontalHeader (see A)

model.sort( 0 , Qt::AscendingOrder );
// However at this point the sort order has been reversed but the
// header's sort indicator remains unchanged (see B)

甲:乙:

如您所见,排序指示符保持不变,因此与实际排序顺序不一致。

在我的应用程序中,我有两个与同一个模型交互的视图,并且可以从它们中的任何一个触发排序。我在 QAbstractItemModel 中看不到任何指示何时执行排序的信号。似乎 QHeaderView/TableView 假设它们是唯一可以触发排序的东西。

Qt 是否提供了处理我所缺少的这个的工具?如果不是,那么在不过多破坏模型上多个视图的封装的情况下,保持排序指示器最新的最佳方法是什么?

【问题讨论】:

我认为排序的发起者应该是视图而不是模型。因此,您可以使用 QTableView::sortByColumn() 函数,IMO 也应该设置排序指示器。 谢谢@vahancho。在我的应用程序中,用户可以从两个视图之一触发排序。在这种情况下,我希望表视图中的排序指示器能够正确同步。我希望这样做,而视图不必直接相互交互...... 如果是这样,您可以为每个视图调用QTableView::sortByColumn(),而不是调用模型的sort() 但这会导致模型多次排序,不是吗?此外,它还要求每个视图“了解”其他视图,这在某种程度上打破了封装:并非所有视图都将始终存在。 【参考方案1】:

自 Qt 4.8 起可用的ItemDataRole 枚举器之一是InitialSortOrderRole

http://qt-project.org/doc/qt-4.8/qt.html#ItemDataRole-enum

因此应该可以通过QAbstractItemModel::headerData 方法传输排序顺序信息。

我已经尝试过了,但发现QTableViewQHeaderView 似乎没有更新以响应此 headerData 角色的更改。自定义标题视图似乎是必要的......

这可能是值得的,因为通过模型传递此信息允许任意数量的视图同步,而无需任何外部代理跟踪存在的所有视图以便它可以分发通知。它还可以通过模型代理堆栈无缝工作,例如使用 QSortFilterModelProxy 构建的那些。

【讨论】:

【参考方案2】:

我想出的避免过多破坏封装的解决方案是

在每个视图上都有一个信号(在 QTableViewsortIndicatorChanged 信号就足够了,在我的自定义视图上我添加了一个类似的信号)。 查看connects 这些信号的经理 当任何视图发出这样的信号时,视图管理器会在所有其他视图上调用一个槽,以便它们可以同步它们的排序指示器

我仍然觉得我可能遗漏了一些东西 - 这肯定是一个常见问题吗?在我看来,QAbstractItemModel 应该有一种将排序顺序信息传输到视图的方法......

【讨论】:

以上是关于模型排序时更新 QTableView/QHeaderView 中的排序指示符的主要内容,如果未能解决你的问题,请参考以下文章

如何将排序结果保存到模型

Qt 5.3.1 TableView 未更新

跨部分重新排序行时更新无效

从数据模型更新 NSManagedObject 类定义

关注 AppEngine 上的数据存储模型结构 - 按日期排序关注者

laravel 本地作用于 模型查询