QTreeView与QAbstractItemModel:树项目在添加/更新新子项时崩溃和消耗

时间:2016-05-19 10:33:42

标签: qt qtreeview qabstractitemmodel

我有一个QTreeView和我自己的模型。将新项目添加到树中时,某些项目会展开或折叠。如何在修改树时保留展开状态?

谢谢你,马丁。

2 个答案:

答案 0 :(得分:1)

我想分享一些代码,但它太长了。我将解释我的问题在哪里。

这是我的树形结构

enter image description here

插入/删除行时必须使用以下功能。

void QAbstractItemModel::beginInsertRows(const QModelIndex & parent, int first, int last);
void QAbstractItemModel::endInsertRows()

void QAbstractItemModel::beginRemoveRows(const QModelIndex & parent, int first, int last)
void QAbstractItemModel::endRemoveRows()

我发现在插入/删除项目A和C时,需要使用无效模型索引作为父索引。无效的模型索引是没有任何参数的QModelIndex()。至少这对我的情况有帮助。

此处提供了一个简单的树模型示例: http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

答案 1 :(得分:1)

对于这个问题的作者来说已经很晚了,但我遇到了类似的问题并最终到了这里,所以也许值得发布我想出的解决方案。

我的理解是更新节点不是问题 - 索引不会失效并且节省了扩展。但是,添加新节点时,默认似乎是使节点折叠。暂停小黑客会更改默认值以扩展所有新添加的索引:

// This is done at the point where the model is set to be used by the view
connect(&model, &QAbstractItemModel::rowsInserted,
        [&](const QModelIndex &parent, int first, int last) {
          for (; first <= last; ++first) {
            tree_view->expand(
                model.index(first, 0, parent));
          }
        });

如果您想用新版本替换节点(删除它并在其位置添加新节点),您可以使用类似的方法:通过连接到QAbstractItemModel::rowsAboutToBeRemoved并使用{{1}来记住扩展}。状态可以在连接到QTreeView::isExpanded()的函数/插槽中恢复。