动态树模型 (Qt)
Posted
技术标签:
【中文标题】动态树模型 (Qt)【英文标题】:Dynamic Tree Model (Qt) 【发布时间】:2014-02-11 18:41:37 【问题描述】:我使用QAbstractItemModel
来表示树模型(最多包含几个猎物)。数据本身是动态的,任何时候节点都可能出现或消失,值(或其他角色)可能会发生变化。
对模型进行更改很容易;我想知道如何有效地发出信号以通知 QTreeView 的变化(它的大部分节点都折叠了)。
在任何给定时间,多个更改可能同时发生(行插入和/或删除)。
-
使用
beginInsertRows
/ endInsertRows
/ beginRemoveRows
/ endRemoveRows
- 不应该有通知视图多个更改的方法吗?
就性能而言,最佳策略是什么?例如,从叶子开始直到每个节点的根 / 从下到上(相对于从上到下)/在插入之前删除 / 等等。
beginResetModel
/ endResetModel
的效率会不会低一些?
使用QStandardItemModel
有什么好处吗? (针对这种特定情况)。
【问题讨论】:
【参考方案1】:是的。通知每个人 disjoint 删除/添加的方法是发出多个信号。在大多数情况下,它会导致更多的开销来传递一些复杂的数据结构,而不仅仅是父索引和分隔行/列索引。
您应该只通知删除/添加靠近根的项目。如果他们的父母随后消失,则通知孩子被带走是没有意义的。关于父母的通知意味着孩子显然已经不在了。
这不仅关乎效率,还关乎状态。模型重置会重置视图状态。视图在收到重置后,只能假设它获得了一个全新的、不相关的模型——因此您会丢失选择、展开/折叠状态等。视图无法以任何其他方式面对重启。否则,视图需要保留自己的模型内容副本。
由于模型重置意味着对所有项目进行重新布局,而且这可能是一件非常昂贵的事情,因此只有在总计超过 50% 的原始项目被更改(移除/替换)时,您才应该这样做/添加)。
不,没有优势,除非您将数据存储为变体,否则使用QStandardItemModel
总是会导致更大的内存开销。如果它完全符合您的需求,那么它是一个很有意义的便利类。事实上,如果你不小心如何使用它,它会变得更糟。
例如,如果您通过迭代深度优先并首先删除最远的孩子来删除一个项目,那么QStandardItemModel
无法预见未来——也就是说,您真的想删除所有这些的共同祖先孩子,并且会发出很多不必要的变化事件。您可以在自己的模型中正确处理它,或者如果您只是删除公共父级而不接触子级 - 因为它们也将被隐式删除。
【讨论】:
以上是关于动态树模型 (Qt)的主要内容,如果未能解决你的问题,请参考以下文章