【发布时间】:2020-05-12 11:54:12
【问题描述】:
我不清楚从 QAbstractItemModel 派生的自定义模型类中删除分支的正确方法是什么。我有一个方法应该刷新树节点(删除所有子分支并插入新的)。
void SessionTreeModel::refresh(const QModelIndex &index, const DbObjectI *object)
{
auto item = getItem(index);
assert(item != nullptr);
if (item != nullptr)
{
if (item->childCount() > 0)
{
beginRemoveRows(index, 0, item->childCount() - 1);
item->removeAll();
endRemoveRows();
}
if (object != nullptr && object->getChildCount() > 0)
{
beginInsertRows(index, 0, static_cast<int>(object->getChildCount()) - 1);
item->appendChildren(object);
endInsertRows();
}
}
}
void SessionTreeItem::removeAll()
{
for (auto& child : childItems_)
{
child->removeAll();
}
childItems_.clear();
}
问题是当调用 'beginRemoveRows()' 时,应用程序经常在几次刷新后崩溃,根据调用堆栈,问题是 SessionTreeModel::parent() 被调用一个包含悬空内部指针的索引。
QModelIndex SessionTreeModel::parent(const QModelIndex &child) const
{
if (child.isValid())
{
auto childItem = getItem(child);
auto parentItem = childItem->parent();
if (parentItem != nullptr &&
parentItem != rootObject_.get())
{
return createIndex(static_cast<int>(parentItem->childCount()),
0, parentItem);
}
}
return QModelIndex{};
}
看起来树视图正在为已删除并试图获取其父项的项保存索引。
你能告诉我可能出了什么问题吗?
【问题讨论】:
-
不是真正的帮助,而是某种提醒:我害怕地记得让我们的 Qt 自定义树模型稳定是一场噩梦。最后,我没有比管理
std::set中的所有自定义节点更好的方法来检查(指针)QModelIndex::internalId()是否(仍然)有效。之前,我在QAbstractItemModel的几乎每个被覆盖的虚拟方法中都添加了打印调试,以了解何时调用它们中的哪一个(以及何时可能存在意外的嵌套调用)。经过一次又一次的耐心和调试,终于稳定下来了。 (我希望。)
标签: c++ qt crash qabstractitemmodel