首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QTreeView/QAbstractItemModel delete导致异常

QTreeView/QAbstractItemModel delete导致异常
EN

Stack Overflow用户
提问于 2016-10-11 02:27:26
回答 1查看 500关注 0票数 0

我编写了一个从QAbstractModelItem派生的类。它在QTreeView上使用。遗憾的是,正式文档示例没有显示如何在模型上添加或删除项目。我以为这样做很容易,所以我用我的方式破解了它。问题是删除选定的对象会导致异常。示例:

用户单击QTreeView上的一行,并希望删除它的所有子行(如果有的话)。这是被执行的代码:

代码语言:javascript
复制
MyModel.cpp:

// This gets called with the QModelIndex of the currently selected row.
void MyModel::remove(const QModelIndex &index) {
    if (!index.isValid()) 
        return;
    MyItem * selectedItem = static_cast<MyItem*>(index.internalPointer());
    beginRemoveRows(index, index.row(), index.row());
    // Call the method on the selected row object that will delete itself and all its children:
    selectedItem->destroy();
    endRemoveRows();
}

MyItem.h:

// A pointer list with child items.
std::vector<MyItem*> children;

MyItem.cpp:

// Deletes all children of this object and itself.
void MyItem::destroy(bool isFirst) {
    if (children.size() > 0) {
        // Each child needs to run this function, to ensure that all nested objects are properly deleted:
        for each (auto child in children)
            child->destroy(false);
        // Now that the children have been deleted from heap memory  clear the child pointer list:
        children.clear();
    }
    // This boolean determines wether this object is the selected row/highest object in the row hierachy. Remove this object from the parent's pointer list:
    if(isFirst)
        parent->removeChild(this);
    // And lastly delete this instance:
    if(!isFirst) // This will cause a memory leak, but it is necessary
        delete this; // <- because this throws an exception if I run this on the first object.
}

// Removes a single child reference from this instance's pointer list.
void MyItem::removeChild(MyItem * child)
{
    auto it = std::find(children.begin(), children.end(), child);
    children.erase(it);
}

现在,如果我们不介意小内存泄漏的话,这就很好了。^^

但是,如果我试图对第一个/选定的row对象运行delete命令,那么就会出现两个例外之一:

  1. 该行有子行:引发的异常:读取访问冲突。这是0xDDDDDDDD.
  2. 该行没有子行:引发的异常:写入访问冲突。_Parent_proxy为0x64F30630.

我保持了代码的简短,但希望它包含我的错误。或者有人知道一个很好的QTreeView/QAbstractItemModel示例,它演示了如何添加/删除项?

向索拉问好

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-11 14:56:53

我认为MyModel::remove方法有一个错误。beginRemoveRows将父索引作为第一个参数,而不是索引本身。你必须用这句话代替这句话:

代码语言:javascript
复制
beginRemoveRows(index.parent(), index.row(), index.row());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39969623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档