c++multithreadingqtqpixmapqmutex

Pixmap shared between threads in Qt


I've got a main GUI class and another Worker class: the first copes with GUI things (drawing a QPixmap into a QGraphicsScene), the second with computations thing (drawing QLines and QPoints onto that QPixmap). The two classes run in two different threads. When I create the Worker thread, I pass the address of the GUI's QPixmap to the Worker class, so they share the same object.

The QPixmap is modified in the Worker class, and drawn in the GUI class. Even if I didn't have any problem, I decided to use a QMutex to ensure my program wouldn't try to access the QPixmap while it was being drawn. Now, in order to do this, I have a QMutex shared between GUI class and Worker class (Worker class has again a pointer to the GUI's QMutex). Whenever I read or modify the QPixmap I lock the QMutex.

Is this a valid approach? I never got errors so far, but I wonder if it is logically correct and whether Qt provides a better way to accomplish this.

Thank you in advance.


Solution

  • According to the Qt5 thread-safety page:

    QPainter can be used in a thread to paint onto QImage, QPrinter, and QPicture paint devices. Painting onto QPixmaps and QWidgets is not supported.

    So the official line is no, you should not be modifying a QPixmap outside of the main thread. You may be "getting lucky" in that it happens to work on your current platform under your current use case, but Qt doesn't guarantee that it will work.

    A safer approach might be to have your worker thread draw into a QImage object instead, and then when the GUI thread wants to update the GUI, it can grab and draw the latest version of the QImage object (using mutexes or some other mechanism to make sure that the worker thread isn't simultaneously updating the QImage).