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 QLine
s and QPoint
s 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.
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).