assembly 删除QGraphicsItem时崩溃

n9vozmp4  于 2023-05-23  发布在  其他
关注(0)|答案(5)|浏览(344)

我想移除QGraphicsScene中的所有项目并删除它们。像这样

QGraphicsItem * item = NULL;
foreach(item, scene->items())
{
    scene->removeItem(item);
    delete item;
}

然而,在运行这段代码并从循环中出来之后,它就因为分段错误而崩溃了。在调试模式下,调试器跳转到汇编文件:

出了什么问题?

pieyvz9o

pieyvz9o1#

这是因为qt使用了BSP树索引来更有效地查找条目。
1.你可以在CustomItem的解构器中使用removeFromIndex()来从BSP树中删除该项目。
1.或者使用m_scene->setItemIndexMethod(QGraphicsScene::NoIndex);禁用QGraphicsScene使用BSP Tree ;
1推荐

8xiog9wr

8xiog9wr2#

如果你要从场景中删除所有的项目,为什么不像下面这样做“清除”呢?你有场景对象与你的权利。
sort();
根据文件:void QGraphicsScene::clear()
移除并删除场景中的所有项目,但在其他情况下使场景的状态保持不变。
这个函数是在Qt 4.4中引入的。

vdgimpew

vdgimpew3#

代码看起来还可以,但我同意只使用QGraphicsScene::clear更有意义;它确实做到了这一点,我的猜测是,它更有效。
如果你已经派生了你自己的QGraphicsItem对象,那么检查你的派生类中的析构函数是否有多个内存删除。您可能会混淆哪个对象拥有特定的指针,导致两个不同的项释放同一内存。

a9wyjsp7

a9wyjsp74#

你使用指针,当你使用函数clear时,它调用子对象的析构函数,但是对于指针,你必须销毁所有指针。不要使用foreach,尝试使用一个简单的for循环,因为foreach使用迭代器,我认为迭代器在删除后无效。

for(int i=0; i < v.size(); ++i)
{
     delete v[i];
     v[i] = nullptr ;
 }
kqhtkvqz

kqhtkvqz5#

答案很晚,但有人可能会觉得有用。
我已经多次遇到这个问题,不仅是在删除项目时,而且在更改项目的位置或尺寸时。
每一次都有效的方法就是

item->prepareGeometryChange();

在执行任何删除/更改尺寸之前。
为什么不知道。

相关问题