在对模型进行排序时,更新QTableView / QHeaderView中的排序顺序指示器

时间:2014-06-02 11:46:22

标签: qt qtableview qt4.8 qabstractitemmodel qheaderview

我想知道如何确保在对模型执行编程排序时更新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)

答:A: immediately after setSortingEnabled(true) B:Immediately after model.sort(0,Qt::AscendingOrder)

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

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

Qt是否提供了应对这种我缺失的设施?如果没有,那么在不破坏模型上多个视图的封装的情况下,保持排序指示器最新的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

自Qt 4.8以来可用的ItemDataRole个调查员之一是InitialSortOrderRole

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

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

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

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

答案 1 :(得分:0)

我提出的避免过度封装的解决方案是

  • 在每个视图上显示一个信号(在QTableView sortIndicatorChanged信号上就足够了,在我的自定义视图中我添加了一个类似的信号。
  • 视图管理员connect对这些信号
  • 当任何视图发出这样的信号时,视图管理器会调用所有其他视图上的插槽,以便他们可以同步其排序指示符

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