何时从发射化QAbstractItemModel dataChanged(When to emit

2019-09-03 07:51发布

在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的因子减小的信号的数目。

这似乎并不理想不过。 任何其他建议任何人吗?

Answer 1:

我们希望你让你的看法知道 ,只要任何数据得到改变。 这“让知道”可以通过多种方式发生; 发光dataChanged是当索引的结构没有改变的最常见的一种; 别人是“严重”的像modelResetlayoutChanged 。 通过巧合,一些Qt的意见都能够拿起变化,即使没有dataChanged上如鼠标悬停,但你不应该依赖于这一点。 这是一个实现细节和可能发生变化。

要回答你的问题的最后一位,是的, dataChanged必须每当从返回的任何数据发出QAIM::data()的变化,即使是“只”比其他一些角色Qt::DisplayRole

你引用的性能问题。 什么是实实在在的数字 - 你实际上得到任何可测量的放缓,还是你只是过早地担心,这可能以后是一个问题? 你知道的事实,你可以使用这两个参数的dataChanged信号在指数的大矩阵的变化?

编辑:

一对夫妇更多的事情尝试:

  • 请确保您的视图不要求额外的数据。 例如,除非你设置QTreeViewuniformRowHeights (这个),该视图将必须执行为O(n)调用为每个dataChanged信号,导致为O(n ^ 2)的复杂度。 那很糟。

  • 如果你真的相信有没有办法解决这个,你可能会通过合并脱身layoutAboutToBeChangedupdatePersistentIndexeslayoutChanged 。 正如你实际上并没有改变你的索引结构,这可能是相当便宜。 然而,前一个点的优化机会还是值得服用。



文章来源: When to emit dataChanged from a QAbstractItemModel