模型排序时更新 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
方法传输排序顺序信息。
我已经尝试过了,但发现QTableView
和QHeaderView
似乎没有更新以响应此 headerData 角色的更改。自定义标题视图似乎是必要的......
这可能是值得的,因为通过模型传递此信息允许任意数量的视图同步,而无需任何外部代理跟踪存在的所有视图以便它可以分发通知。它还可以通过模型代理堆栈无缝工作,例如使用 QSortFilterModelProxy
构建的那些。
【讨论】:
【参考方案2】:我想出的避免过多破坏封装的解决方案是
在每个视图上都有一个信号(在QTableView
上 sortIndicatorChanged
信号就足够了,在我的自定义视图上我添加了一个类似的信号)。
查看connect
s 这些信号的经理
当任何视图发出这样的信号时,视图管理器会在所有其他视图上调用一个槽,以便它们可以同步它们的排序指示器
我仍然觉得我可能遗漏了一些东西 - 这肯定是一个常见问题吗?在我看来,QAbstractItemModel
应该有一种将排序顺序信息传输到视图的方法......
【讨论】:
以上是关于模型排序时更新 QTableView/QHeaderView 中的排序指示符的主要内容,如果未能解决你的问题,请参考以下文章