在 Qt 中,我有一个模型子类化QAbstractItemModel
- 它是显示在 QTreeView 中的树。
该模型支持各种形式的更改,并且都可以正常工作。相关的两个是:
1)少量相关行中的部分数据发生变化
2) 可视化更改意味着大多数行应更改其格式 - 特别是背景突出显示的更改。他们的DisplayRole
数据不会改变。
当前的设计以相同的方式处理这两个问题:对于模型发出的每一行发生的任何更改dataChanged(start_of_row_index,end_of_row_index)
。我为发生变化的父行及其任何发生变化的子行发出信号。
然而,随着模型变大,在情况 2 中这会表现得很差:大量的dataChanged
发出信号。
我更改了代码,以便在情况 2 中模型发出dataChanged
仅适用于作为整个树的父级的(单)行。
这似乎仍然可以正确工作,但不符合我对模型职责的理解。但我怀疑我可能是错的。
也许我误解了dataChanged
信号?它实际上会导致视图更新所有子级以及指定范围吗?或者我可以避免排放dataChanged
当它不是DisplayRole
那正在改变吗?
编辑了我迄今为止的进展
正如简指出的那样,我应该发出dataChanged
对于情况 2 中的大多数或全部行。
我的代码最初是通过发出来做到这一点的dataChanged
对于每个更改的行,但这太昂贵了 - 视图需要太长时间来处理所有这些信号。
一个可能的解决方案是聚合dataChanged
为更改行的任何连续块发出信号,但是当例如每隔一行都发生更改时,这仍然无法很好地执行 - 它仍然会发出太多信号。
理想情况下,我只想告诉视图将所有数据视为可能已更改(但所有索引仍然有效 - 布局不变)。对于单个信号来说这似乎是不可能的。
因为一个怪癖QTreeView
类,有可能(尽管根据规范不正确)只发出一个dataChanged(tl,br
) 只要tl != br
。我已经完成了这个工作,它通过了我们的测试,但让我感到紧张。
我现在已经确定了一个遍历树并发出一个单一的版本dataChanged(tl,br)
对于每个父母(tl,br 涵盖该父母的所有孩子)。这符合模型/视图协议,对于我们的模型来说,它通常会将信号数量减少大约 10 倍。
然而,这似乎并不理想。还有其他建议吗?