删除行时 QModelIndex 变得无效
QModelIndex becomes invalid when removing rows
我正在子classing QAbstractItemModel
显示 QTreeView
中的项目,并且在这个子class (projectModel
) 中,我有删除树视图中当前选定索引的函数。 Component
是class用来表示模型的所有成员:
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()
:
中崩溃
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
之间被破坏了。我正在做的事情是否有明显的错误,或者问题可能更微妙?
这完全符合预期。
非持久性索引在您更改模型结构之前一直有效。结构变化是指 other 而不是发出 dataChanged
.
信号的任何变化
必须将结构更改视为索引生命周期的障碍:您必须丢弃在结构更改之前保留的任何非持久索引。
根据调用 deleteComponent
的位置,可能发生的情况是调用者持有一些索引,deleteComponent
使它们全部无效,并且您从那里开始处于未定义的行为区域。
如果您希望持久性索引在结构更改时保持有效,则需要使用持久性索引,即便如此,它们也只有在给定项目仍然存在时才有效。如果您使用自己的模型,则需要明确支持持久性索引,并且模型的用户必须使用它们。
我正在子classing QAbstractItemModel
显示 QTreeView
中的项目,并且在这个子class (projectModel
) 中,我有删除树视图中当前选定索引的函数。 Component
是class用来表示模型的所有成员:
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()
:
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
之间被破坏了。我正在做的事情是否有明显的错误,或者问题可能更微妙?
这完全符合预期。
非持久性索引在您更改模型结构之前一直有效。结构变化是指 other 而不是发出 dataChanged
.
必须将结构更改视为索引生命周期的障碍:您必须丢弃在结构更改之前保留的任何非持久索引。
根据调用 deleteComponent
的位置,可能发生的情况是调用者持有一些索引,deleteComponent
使它们全部无效,并且您从那里开始处于未定义的行为区域。
如果您希望持久性索引在结构更改时保持有效,则需要使用持久性索引,即便如此,它们也只有在给定项目仍然存在时才有效。如果您使用自己的模型,则需要明确支持持久性索引,并且模型的用户必须使用它们。