删除行时QModelIndex变为无效 [英] QModelIndex becomes invalid when removing rows
问题描述
我将QAbstractItemModel
子类化以显示QTreeView
中的项目,并且在此子类(projectModel
)中,我具有删除树状视图中当前选定索引的功能. Component
是用于表示模型的所有成员的类:
I'm subclassing QAbstractItemModel
to display items in a QTreeView
, and within this subclass (projectModel
), I have a function to delete the currently-selected index in the tree view. Component
is the class used to represent all the members of the model:
void
projectModel::deleteComponent()
{
QModelIndex child_index = _treeview->selectionModel()->currentIndex();
Component* child = static_cast<Component*>(child_index.internalPointer());
Component* parent = child->Parent();
QModelIndex parent_index = createIndex(parent->row(), 0, parent);
int row = child->row();
beginRemoveRows(parent_index, row, row);
parent->delete_child(child);
endRemoveRows();
}
在调用beginRemoveRows
之前,父级和子级索引以及原始指针都很好;调试器显示它们指向正确的项及其父项.但是,调用beginRemoveRows
后程序崩溃.具体来说,它在projectModel::parent()
中崩溃:
The parent and child indicies and raw pointers are good just before the call to beginRemoveRows
; debugger shows that they point to the correct item and its parent. However, the program crashes after calling beginRemoveRows
. Specifically, it crashes in projectModel::parent()
:
QModelIndex
projectModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
Component* item = getItem(index); //Fails to cast index internal pointer to a valid Component*
Component* parentItem = item->Parent();
if (parentItem == _rootnode)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
当我在崩溃中休息并检查调试器输出时,它表明parent()
函数中的变量item
是垃圾.某种程度上,我的QModelIndex
在调用deleteComponent
和parent
之间被损坏了.我所做的事情有什么公然的错误吗?还是这个问题可能更微妙了?
When I break on the crash and examine the debugger output, it shows that the variable item
in the parent()
function is garbage. Somehow it looks like my QModelIndex
gets corrupted between the call to deleteComponent
and the call to parent
. Is there anything blatantly wrong with what I'm doing, or is the problem perhaps more subtle?
推荐答案
完全可以预期.
非持久索引有效,直到您更改模型的结构.结构性变化是 other 发出的信号,而不是发出dataChanged
的任何信号.
Non-persistent indices are valid until you change the structure of the model. A structural change is any change that is signaled other than by emitting dataChanged
.
必须将结构更改视为索引寿命的障碍:必须丢弃结构更改之前保存的所有非持久索引.
Structural changes must be considered barriers to index lifetime: you must discard any non-persistent indices held from before a structural change.
根据调用deleteComponent
的位置,可能发生的情况是调用方拥有一些索引,所有deleteComponent
都使它们无效,并且您从此一直处于未定义的行为领域.
Depending on where deleteComponent
is called, likely what happens is that the caller holds some indices, the deleteComponent
invalidates them all, and you're in undefined behavior territory from there onwards.
如果您希望持久索引在结构更改上保持有效,则需要使用持久索引,即使这样,它们也仅在给定项仍然存在的情况下才有效.如果您使用自己的模型,则需要显式支持持久索引,并且模型的用户必须使用它们.
You need to use persistent indices if you want them to stay valid over structural changes, and even then they'll only be valid if the given item still exists. If you're using your own model, you need to explicitly support persistent indices, and the users of your model must use them.
这篇关于删除行时QModelIndex变为无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!