Important: Please read the Qt Code of Conduct -

Using the GraphicsItem tree hierarchy in a worker thread

  • This is not the usual questions whether "GraphicsView can be made to work multi-threaded". I'm actually fine doing all my painting in the main thread.


    The tree hierarchy I can create between multiple QGraphicsItem-based objects is useful not only for displaying, but also as a data structure.

    The question is: Is it safe to use GraphicsView classes in a multi-threaded environment, when all you need is the item tree (that is, the parent-child relationships between items)?

    Let me explain the context.

    I let the user populate a scene with different GraphicsItem subclasses, in an editor-like environment. Those scenes can get pretty complex, and items can be grouped, etc. In the end, we have a tree-like data structure, with the GraphicsScene as the root. I can save this structure, and later load it again. So far so good, all in the main thread.

    Now assume I want to just parse the data structure, to locate information that has, in effect, nothing to do with drawing or user interaction. The only thing I need is the data members I added in my GraphicsItem subclasses, and the structure. So I would like to load the scene, parse for the information I need, then unload it again. And I'd like to be able to move that to a worker thread.

    No painting, no user interaction, the scene is actually never connected to a GraphicsView...but I still have my QGraphicsItem base classes. And they are not marked as re-entrant. So even when just calling constructor, destructor and parentItem, I run into a risk that something goes awry, if I am doing it in different threads. Or so the documentation would suggest.

    An alternative would be to create a parallel data structure that is totally independent from GraphicsView classes. But that's really ugly.

  • If you solely use the scene tree from the other thread, and only do reads (no modifications) you can just give it to your thread. The issue with re-entrance is only if multiple threads are accessing the tree in parallel, which does not seem to be your case. Anyway if that scares you, you can explicitely set the scene tree thread affinity by using QGraphicsScene::moveToThread(), although I'm sure this would be useless. Loads and unloads have to happen in the same thread however.

  • True. As long as only one thread is working on the data (and I can make sure no-one else is fooling around with it), then I should be able to safely hand it over to another thread.


Log in to reply