I am troubled by the following:
I am working with an interactive QGraphicsScene
that needs to render the graphical representation of an SQL query, based on the users' operations, such as: add something to the query (a table, a new column, something else) or remove something from the query (a keyword, a table, a column ...). The changes of the scene must be displayed after the operation, and also the "logic layer" of the application needs to track the operations the user did, since the "rendering" of the query is done by the "logic" layer (ie: the "logic layer" creates all the QGraphicsItemGroup
derived objects which at a later stage, after all the logic layer components were built, are being added to the graphics scene of the query and put on the window).
The problem that occurs is the following: right now I did not manage to find any usable solution to present a query after a change in the smoothest possible way.
Allow me to link in a screenshot for further explanation:
Let's suppose the user wants to remove the PERSON.NAME
column from the query. What happens in the application:
PERSON.NAME
columns' graphic itemPERSON.NAME
column, And here the trouble starts:
PERSON.NAME
QGraphicsScene
object together with a QGraphicsView
PERSON.NAME
column) into the new QGraphicsScene
with addItem()
PERSON.NAME
is not there anymore and all the graphic elements that were below PERSON.NAME
were moved up on the screen.Obviously this is not a good solution, there is an ugly flickering when I change the window, but I simply did not find a better solution to this problem till now.
So I am asking for your help in order to identify what improvements can be done to this methodology of updating the screen upon removal (addition) of a new element knowing the background information above, without a new window. Obviously other, mroe generic graphic related comments are welcome too.
Thanks,f
Based on the information from the question and the comments, a couple of things you could consider:
First thing is that you need to get rid of creating a new Window and a new QGraphicsView
when refreshing.
I suppose this is the main reason for flickering. Keep your UI structure unmodified and only modify the scene.
You could use one of these approaches:
Either create a new QGraphicsScene
and set it as the view's scene, or call clear()
on
the existing scene. Then recreate your QGraphicsItems
from your native model and make sure that all your pointers and references are updated.
Another approach would be to have the QGraphicsScene
update your native model when something changes, to avoid the need to recreate the whole scene from scratch. For example, let the QGraphicsScene
handle the deletion of the QGraphicsItem
when the user clicks the delete icon, and then let the scene update your native model to reflect this change.
Yet another approach would be to discard your native model, and use the QGraphicsScene
with its QGraphicsItems
as your model. Implement serialization etc. in the scene class. This avoids the need to synchronize the two models. The drawback is that your graphics independant logic is then much tighter coupled to the QGraphicsScene
, which you might not want. Depending on your code size, this might also be a lot of work.
I would start with 1., since it seems to be the easiest way to go based on your existing approach. If you still come across weird issues with pointers and object ownership, try to isolate them and ask on SO :)