动态树模型(Qt)

时间:2014-02-11 18:41:38

标签: qt qt4 pyqt4 pyside qabstractitemmodel

我使用QAbstractItemModel来表示一个树模型(最多几个hounded项)。数据本身是动态的,在任何时候节点可能出现或消失,值(或其他角色)可能会改变。

轻松更改模型;我想知道如何有效地发出信号,以便通知QTreeView变化(大多数节点都被折叠)。

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

  1. 使用beginInsertRows / endInsertRows / beginRemoveRows / endRemoveRows - 是否应该有一种方法来通知视图多次更改?
  2. 在绩效方面,最佳策略是什么?例如,从叶子开始并上升到根/每个节点 - 从插入/等之前的底部到顶部(vs顶部到底部)/删除。
  3. beginResetModel / endResetModel效率会降低吗?
  4. 使用QStandardItemModel有什么好处吗? (针对这种具体情况)。

1 个答案:

答案 0 :(得分:3)

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

  2. 您应该只通知关闭根目录的项目的删除/添加。如果他们的父母随后消失,通知移除儿童是没有意义的。关于父母的通知意味着孩子们显然不在那里了。

  3. 这不仅关乎效率,还涉及国家。模型重置会重置视图状态。视图在收到重置后,不得不假设它有一个全新的,不相关的模型 - 因此你会丢失选择,扩展/折叠状态等等。视图无法以任何其他方式执行操作重启。否则,需要一个视图来保留自己的模型内容副本。

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

  4. 不,没有优势,除非您将数据存储为变体,否则使用QStandardItemModel将始终会产生更大的内存开销。如果它完全符合您的需求,它是一个有意义的便利类。事实上,如果你不小心使用它,它会更糟糕。

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