QGraphicsScene::clear() clearing scene but not the view

TeaOverflow picture TeaOverflow · Sep 15, 2012 · Viewed 16.7k times · Source

I use a custom class (Configuration) derived from QGraphicsItem and I add its objects to a QGraphicsScene, which is then displayed in a QGraphicsView. Usual stuff. What Im doing exactly is drawing a tree, in multiple steps, one level a step, each node beeing my custom QGraphicsItem.

enter image description here

Here a screenshot. The tree happens to be sequential in the simple case.

I first draw the root node. The signal that triggers that is fired after the user entered a string.

void MainWindow::drawRootSlot(ConfigTreeBuilder & builder)//this is a slot
{
    c_scene->clear();  //the clear cause headache. i'll expain

    Configuration* conf = new Configuration(builder.getNodesX(), builder.getNodesY(),builder.getNodesConfig());
//code
    c_scene->addItem(conf);
//code
}

Each subsequent Configuration is draw inside another slot.

void MainWindow::configTreeSlot(ConfigTreeBuilder & builder)    //SLOT!!!
{
    while(builder.chooseNextNode()) {

        Configuration* conf = new Configuration(builder.getNodesX(), builder.getNodesY(), builder.getNodesConfig());

       //code, while loop    
            QGraphicsLineItem *edge = c_scene->addLine(QLineF(*(parentsPoint), conf->getLeftOrigin()));
            edge->setZValue(-1); //below the Configuration item


        c_scene->addItem(conf);
    }

}

All works fine when done for the first time. When I enter a new string, resetting the tree, dark magic happens. What I expected to it do is: call drawRootSlot(), deleting the whole tree (c_scene->clear()), draw a new root node. And, if I put a debugger breakpoint inside drawRootSlot() this is exactly what happens! But when I run it (without breakpoints), what I get is this:

enter image description here

The previous tree got mangled, but not deleted. The scene gets indeed cleared of its items (printed that) but the view does not reflect that. But again, when I put a breakpoint inside drawRootSlot() thhe view and the scene are in sync.

I tried to delete the scene object, and instaciate a new one instead of calling c_scene->clear(), to guarantee it empty. Then the changes are reflected on the view (the first time drawing always works).

So, I have no idea what to deduce from these symptoms. It works as expected with a breakpoint or with a freshh QGraphicsScene object. It does not when just using c_scene->clear(). One couldsay I just messed up the parent-object/child-object relation, but clear() does remove items from the view... I tried calling it right after c_scene->addItem().

What is this sorrcery? One that makes me believe I'm not actually stupid?

EDIT: Whats interesting and may be a hint to the real problem, is that when c_scene->clear() is called, the edges of the tree, which are normal QGraphicsLineItems, are indeed deleted in all cases (breakpoint or not). Something to do with them not beeing custom?

Answer

TeaOverflow picture TeaOverflow · Sep 16, 2012

Ok, calling QGraphicsView::viewport().update() after QGraphicsScene::clear() solved my problems.

But does anyone have an explanaition to the behavior described above?

EDIT: Upon doing doing something else I stumbled upon the actual core of the problem: I messed up the boundingRect() of my GraphicItems, so it was below the visble item, touching only its lower edge (which got deleted, as seen on the screenshot). So now no calls to any update() methods are neccesary.