My problem is a simple yet annoying user experience damaging one. I'm trying to display huge amounts (10 of thousands) of custom QGraphicsItem
s on a QGraphicsScene
. I would also require a QGraphicsLayout
, but to my understanding one could not simply put a layout on a scene, for that the layout have to be set on a QGraphicsWidget
and then the widget added to the scene.
Now when I need to load a large number of items and prepare them to be displayed the scene just sits there empty, because I can't invalidate or repaint the aforementioned QGraphicsWidget
. Only in the end it can be added to the scene otherwise any later change will not be displayed.
The goal: add some kind of layout management to scene -> {prepare an item -> add item to layout -> display -> prepare an item ->} repeat ...
But what I have: {prepare an item -> prepare another item ->} repeat ... -> add everything to layout -> set layout management on scene -> display
So the question: What way is there to create a responsive layout/container to the scene, one which repaints itself after a new child is added to it?
From Qt manual:
It does not mention about addItem() and removeItem(). Hopefully, these are covered also.
If so your could apply the following:
A signal handler may "catch" the change and requests the repaint (e.g. by invalidate()) of the scene. (Un-)Fortunately, this does not immediately repaint the scene (with its parent view) but does queue a repaint event. Thus, the actual repaint is not done until the event loop is passed again.
(The event loop is part of the QApplication. If you stop your application inside a command initiated by the user interface you will find in the callstack something like this:
)
You can force this by calling QApplication::processEvents(). (It's even static.) AFAIK, it is usually no problem if event loops are nested because they are prepared for this (as long as no non-terminated recursion is formed).
However, this probably needs some fine-tuning because too many repaints may slow down your application massively.