QModelIndex becomes invalid when removing rows

吃可爱长大的小学妹 提交于 2019-12-10 16:06:48

问题


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();
}

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);
}

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?


回答1:


This is fully expected.

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.

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.



来源:https://stackoverflow.com/questions/31569424/qmodelindex-becomes-invalid-when-removing-rows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!