str*_*bly 4 qt qtreeview qabstractitemmodel
在Qt中,我有一个模型子类QAbstractItemModel- 它是一个在QTreeView中显示的树.
该模型支持各种形式的变更,这些变更都可行.两个相关性是:
1)少量相关行中的一些数据发生变化
2)可视化更改意味着大多数行应更改其格式 - 特别是它们会更改背景突出显示.他们的DisplayRole数据没有变化.
当前的设计以相同的方式处理这两个方面:对于每个有任何变化的行,模型都会发出dataChanged(start_of_row_index,end_of_row_index).我为两个更改的父行以及已更改的任何子项发出信号.
然而,当模型变大时,这在情况2中表现很差:dataChanged发射了大量信号.
我已经更改了代码,以便在案例2中,模型dataChanged仅针对作为整个树的父级的(单个)行发出.
这仍然可以正常工作,但不符合我对模型责任的理解.但我怀疑我可能错了.
也许我误解了这个dataChanged信号?它是否真的导致视图更新所有子项以及指定的范围?或者,dataChanged当它不是在DisplayRole变化时,我可以避免发射吗?
正如Jan指出的那样,dataChanged在案例2中,我应该为大多数或所有行发射.
我的代码最初通过dataChanged为每个更改的行发出这个来做到这一点,但这太贵了 - 视图处理所有这些信号需要太长时间.
一种可能的解决方案可能是聚合dataChanged任何连续变化行块的信号,但是当例如每隔一行发生变化时,这仍然不能很好地执行 - 它仍然会发出太多信号.
理想情况下,我想告诉视图将所有数据视为可能已更改(但所有索引仍然有效 - 布局未更改).单个信号似乎不可能实现这一点.
由于类的怪癖QTreeView,只要有可能(虽然根据规范不正确)只发出一个dataChanged(tl,br)tl != br.我有这个工作,它通过了我们的测试,但让我感到紧张.
我现在已经解决了遍历树的版本并dataChanged(tl,br)为每个父级发出一个单独的版本(使用tl,br跨越该父级的所有子级).这符合模型/视图协议,对于我们的模型,它通常将信号数量减少大约10倍.
然而,它似乎并不理想.有人提出其他建议吗?
每当有任何数据发生变化时,您都应该知道您的观点.这种"让人知道"可以通过多种方式发生; dataChanged当索引的结构没有改变时,发射是最常见的; 其他人是像" modelReset或"这样的"严肃"的人layoutChanged.巧合的是,一些Qt的观点即使没有dataChanged像鼠标悬停也可以获得变化,但你不应该依赖它.这是一个实现细节和一个需要改变的主题.
要回答问题的最后一点,是的,dataChanged每当从QAIM::data()更改中返回任何数据时都必须发出,即使它只是"其他"角色Qt::DisplayRole.
你是在引用性能问题.有哪些难以理解的数字 - 您实际上是否正在获得任何可衡量的减速,或者您是否过早地担心这可能会在以后出现问题?您是否意识到可以使用这两个参数来表示dataChanged对大型索引矩阵的更改?
编辑:
还有几件事要尝试:
确保您的视图不会请求额外的数据.例如,除非设置QTreeView's uniformRowHeights(IIRC),否则视图必须对每个dataChanged信号执行O(n)调用,从而导致O(n ^ 2)复杂度.那很糟.
如果你真的确定没有办法解决这个问题,那么你可以通过组合layoutAboutToBeChanged,updatePersistentIndexes和layoutChanged.由于您实际上并未更改索引的结构,因此这可能相当便宜.然而,前一点的优化机会仍值得一试.
| 归档时间: |
|
| 查看次数: |
13782 次 |
| 最近记录: |