2
votes

I have a QGraphicsView inside a Horizontal Layout. The QGraphicsScene contained in the QGraphics scene is pretty large (thousands of pixels), so scroll bars show up by default to allow me to scroll through the view.

Every time I update the scene inside the graphics scene, I delete the old scene, make a new one, populate it with objects, and call view->setScene(scene). When I do this, however, the scroll bars default to the top left corner of the QGraphicsView, instead of staying where they were at.

I tried saving the QGraphicsScene::sceneRect before destroying the scene, then doing a setSceneRect() afterwards to restore it, but that doesn't work since that only affects the scene itself, not the QGraphicsView that's displaying it. I also tried to do view->verticalScrollBar()->setValue(), but that doesn't appear to affect the scroll bars at all.

How can I access the scroll bars that are created for me by default, and set them to a value that was stored earlier?

2
What is happening in your update to the scene that requires deleting it and recreating it?Arnold Spence

2 Answers

1
votes

Fixed by not deleting previous scene until after the new one is set.

e.g.

QGraphicsScene *previousScene = scene;
scene = new QGraphicsScene(0, 0, levelPlist.value("level_width").toInt(), levelPlist.value("level_height").toInt());

// config scene

QGraphicsView *view = ui->graphicsView;
view->setScene(scene);

delete previousScene;
0
votes

Before I give a possible solution, I would highly recommend an approach that doesn't involve destroying your scene. If you're just clear()'ing your scene, you should be able to call setSceneRect() before clearing it, which will prevent the scene from automatically resizing its rect. When it's repopulated you can call setSceneRect() with a default-constructed QRect to give it control over the size of the rect once again.

If you really need to save/restore the scroll bars as stated, the following approach has worked for me in the past:

I've had to do something similar (for different reasons), and the best solution I've come up involves doing something like this:

  • Before clearing the scene, save off the positions of your vertical and horizontal scrollbars
  • Before reconstructing the scene, connect to the QScrollBar::rangeChanged() signal with a queued signal/slot connection. This signal should get fired after you've repopulated your scene, and it indicates that the scroll bars have been reconfigured by the view.
  • In your slot, disconnect from the rangeChanged() signal, and restore the scroll bar positions

Note that this is pretty much guaranteed to cause some flicker/jumpiness.