删除行时QModelIndex变为无效 [英] QModelIndex becomes invalid when removing rows

查看:535
本文介绍了删除行时QModelIndex变为无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将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在调用deleteComponentparent之间被损坏了.我所做的事情有什么公然的错误吗?还是这个问题可能更微妙了?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆