如何从QGraphicsScene中删除所有QGraphicsItem

时间:2011-09-15 12:47:49

标签: c++ qt incomplete-type

我已经从QGraphicsScene编写了一个派生类。在某一点上,我需要从场景中删除所有项目,我希望物品被物理销毁(析构函数被调用)。我尝试了以下方法:

QList<QGraphicsItem*> all = items();
for (int i = 0; i < all.size(); i++)
{
    QGraphicsItem *gi = all[i];
    removeItem(gi);
    delete gi; // warning at this line
}

Qt Creator发出警告:警告:C4150:删除指向不完整类型'QGraphicsItem'的指针;没有析构函数叫

我不知道为什么会这样。 QGraphicsItem具有虚拟析构函数,因此应该从内存中删除项目。

如果这不是正确的方式,如何从QGraphicsItem删除所有QGraphicsScene?请注意,我知道删除场景后,所有项目也将被删除。但我想从场景中删除项目并绘制其他项目。我希望从内存中删除已删除的项目。

3 个答案:

答案 0 :(得分:18)

您可以使用QGraphicsScene::clear()删除和删除所有项目。

答案 1 :(得分:10)

jpalecek 指出,您缺少头文件。你应该接受他的回答。我只想指出两个潜在的问题:

首先,您无需致电QGraphicsScene::removeItem()QGraphicsItem::~QGraphicsItem()为你做到了。

其次。如果你把任何QGraphicsItem放在别人的内心,要小心。也就是说,您有其他项目的子项。 QGraphicsItem的析构函数会自动删除其所有子项。因此,当您遍历从QGraphicsScene返回的项目时,您最终可能会删除已被其父项删除的子项目。例如,假设您有2个项目,A和B,B是A的子项。删除A时,B会自动删除。然后你到达B并尝试删除它。 BOOM!

更安全的方法是测试该项目是否为顶级项目,即它没有父项:

QList<QGraphicsItem*> all = items();
for (int i = 0; i < all.size(); i++)
{
    QGraphicsItem *gi = all[i];
    if(gi->parentItem()==NULL) {
        delete gi;
    }
}

答案 2 :(得分:7)

你必须

#include <QGraphicsItem>

在该文件中。否则,编译器不知道QGraphicsItem是什么,它有虚拟析构函数等。