删除行时 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 使它们全部无效,并且您从那里开始处于未定义的行为区域。

如果您希望持久性索引在结构更改时保持有效,则需要使用持久性索引,即便如此,它们也只有在给定项目仍然存在时才有效。如果您使用自己的模型,则需要明确支持持久性索引,并且模型的用户必须使用它们。