Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete all QGraphicsItem from QGraphicsScene

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:

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

I'm not sure why is that. QGraphicsItem has virtual destructor so the items should be deleted from memory.

If this is not the right way, how can I delete all QGraphicsItems 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.

like image 323
Donotalo Avatar asked Sep 15 '11 12:09

Donotalo


1 Answers

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:

First of all, you don't need to call QGraphicsScene::removeItem(). QGraphicsItem::~QGraphicsItem() does that for you.

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!

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;
    }
}
like image 95
Stephen Chu Avatar answered Sep 28 '22 15:09

Stephen Chu