2

我用 aQAbstractItemModel来表示一个树模型(最多几个猎物)。数据本身是动态的,任何时候节点都可能出现或消失,值(或其他角色)可能会发生变化。

更改模型很容易;我想知道如何有效地发出信号以通知 QTreeView 的变化(它的大部分节点都折叠了)。

在任何给定时间,多个更改可能同时发生(行插入和/或删除)。

  1. 使用/// beginInsertRows-endInsertRows不应该有一个方法来通知视图多次更改吗beginRemoveRowsendRemoveRows
  2. 就性能而言,最佳策略是什么?例如,从叶子开始直到每个节点的根 / 从下到上(相对于从上到下)/在插入之前删除 / 等等。
  3. beginResetModel/endResetModel必然会降低效率吗?
  4. 使用有什么好处QStandardItemModel吗?(对于这种特定情况)。
4

1 回答 1

3
  1. 是的。通知每个人不相交的删除/添加的方法是发出多个信号。在大多数情况下,它会导致更多的开销来传递一些复杂的数据结构,而不仅仅是父索引和分隔行/列索引。

  2. 您应该只通知删除/添加靠近根的项目。如果他们的父母随后消失,则通知孩子被带走是没有意义的。关于父母的通知意味着孩子们显然已经不在了。

  3. 这不仅关乎效率,还关乎状态。模型重置会重置视图状态。视图在收到重置后,只能假设它获得了一个全新的、不相关的模型——因此您会丢失选择、展开/折叠状态等。视图无法以任何其他方式面对重启。否则将需要视图保留自己的模型内容副本。

    由于模型重置意味着所有项目的重新布局,而且这可能是一件非常昂贵的事情,因此您应该只在总体上超过 50% 的原始项目被更改(删除/替换/添加)时才这样做.

  4. 不,没有优势,除非您将数据存储为变体,否则使用QStandardItemModel总是会导致更大的内存开销。如果它完全符合您的需求,那么它是一个方便的类。事实上,如果你不小心如何使用它,它的效果会更糟。

    例如,如果您通过迭代深度优先并首先移除最远的孩子来移除一个项目,那么QStandardItemModel就无法预见未来——也就是说,您真的想移除所有这些孩子的共同祖先,并且会发出一个很多不必要的变化事件。您可以在自己的模型中正确处理它,或者如果您只是删除公共父项而不接触子项 - 因为它们也将被隐式删除。

于 2014-02-11T18:54:01.180 回答