I've written a derived class from QGraphicsScene
. At a point I need to remove all items from the scene and I want the items to be physically destroyed (destructor called). I tried the following:
我已经从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 emits a warning: warning: C4150: deletion of pointer to incomplete type 'QGraphicsItem'; no destructor called
Qt创建者发出警告:警告:C4150:删除不完全类型“QGraphicsItem”的指针;没有析构函数叫
I'm not sure why is that. QGraphicsItem
has virtual destructor so the items should be deleted from memory.
我不知道为什么。QGraphicsItem有虚拟析构函数,因此应该从内存中删除这些项。
If this is not the right way, how can I delete all QGraphicsItem
s from QGraphicsScene
? Note that I know when the scene is deleted, all items will also be deleted. But i want to remove items from scene and draw other items. I want the removed items to be deleted from memory.
如果这不是正确的方法,我如何从QGraphicsScene删除所有QGraphicsItems ?注意,我知道当场景被删除时,所有的条目也会被删除。但是我想从场景中移除项目并绘制其他项目。我希望删除的项从内存中删除。
3 个解决方案
#1
17
You can remove and delete all items with QGraphicsScene::clear().
您可以删除和删除所有带有QGraphicsScene的条目::clear()。
#2
10
Like jpalecek pointed out, you are missing the header file. You should accept his answer. I am just going to point out two potential issues:
正如jpalecek指出的,您缺少头文件。你应该接受他的回答。我将指出两个潜在的问题:
First of all, you don't need to call QGraphicsScene::removeItem()
. QGraphicsItem::~QGraphicsItem()
does that for you.
首先,您不需要调用QGraphicsScene::removeItem()。QGraphicsItem::~QGraphicsItem()为您做这个。
Secondly. Be careful if you put any QGraphicsItem
inside of others. That is, you have items that are children of other items. The destructor of QGraphicsItem
automatically delete all its children. So when you loop through the items returned from QGraphicsScene
, you may end up deleting a child item that has already been deleted by its parent. For example, say you have 2 items, A and B, and B is a child of A. When you delete A, B is deleted automatically. And then you get to B and try to delete it. BOOM!
其次。如果你把任何QGraphicsItem放在别人的里面,一定要小心。也就是说,你有其他项目的孩子。QGraphicsItem的析构函数会自动删除所有其子元素。因此,当您循环从QGraphicsScene返回的条目时,您可能会删除已经被其父删除的子条目。例如,假设您有两个项目,A和B, B是A的孩子,当您删除A时,B会自动删除。然后你得到B并试图删除它。繁荣!
A safer way to do this is to test if the item is the top level one, i.e. it has no parent:
一个更安全的方法是测试该项目是否是*的,即它没有父类:
QList<QGraphicsItem*> all = items();
for (int i = 0; i < all.size(); i++)
{
QGraphicsItem *gi = all[i];
if(gi->parentItem()==NULL) {
delete gi;
}
}
#3
7
You have to
你必须
#include <QGraphicsItem>
in that file. Otherwise, the compiler doesn't know what QGraphicsItem
is, that it has a virtual destructor, etc.
在该文件中。否则,编译器不知道QGraphicsItem是什么,它有一个虚拟析构函数,等等。
#1
17
You can remove and delete all items with QGraphicsScene::clear().
您可以删除和删除所有带有QGraphicsScene的条目::clear()。
#2
10
Like jpalecek pointed out, you are missing the header file. You should accept his answer. I am just going to point out two potential issues:
正如jpalecek指出的,您缺少头文件。你应该接受他的回答。我将指出两个潜在的问题:
First of all, you don't need to call QGraphicsScene::removeItem()
. QGraphicsItem::~QGraphicsItem()
does that for you.
首先,您不需要调用QGraphicsScene::removeItem()。QGraphicsItem::~QGraphicsItem()为您做这个。
Secondly. Be careful if you put any QGraphicsItem
inside of others. That is, you have items that are children of other items. The destructor of QGraphicsItem
automatically delete all its children. So when you loop through the items returned from QGraphicsScene
, you may end up deleting a child item that has already been deleted by its parent. For example, say you have 2 items, A and B, and B is a child of A. When you delete A, B is deleted automatically. And then you get to B and try to delete it. BOOM!
其次。如果你把任何QGraphicsItem放在别人的里面,一定要小心。也就是说,你有其他项目的孩子。QGraphicsItem的析构函数会自动删除所有其子元素。因此,当您循环从QGraphicsScene返回的条目时,您可能会删除已经被其父删除的子条目。例如,假设您有两个项目,A和B, B是A的孩子,当您删除A时,B会自动删除。然后你得到B并试图删除它。繁荣!
A safer way to do this is to test if the item is the top level one, i.e. it has no parent:
一个更安全的方法是测试该项目是否是*的,即它没有父类:
QList<QGraphicsItem*> all = items();
for (int i = 0; i < all.size(); i++)
{
QGraphicsItem *gi = all[i];
if(gi->parentItem()==NULL) {
delete gi;
}
}
#3
7
You have to
你必须
#include <QGraphicsItem>
in that file. Otherwise, the compiler doesn't know what QGraphicsItem
is, that it has a virtual destructor, etc.
在该文件中。否则,编译器不知道QGraphicsItem是什么,它有一个虚拟析构函数,等等。