Search code examples
multithreadingqtqpixmapdrawing2d

How to paint onto QLabel in another thread


I've got a specific target: to draw a road-net. So i have a number of dots (x,y) and I'd like to connect them (using drawLine function). Because of their amount (about 2-3 millions) I need to do in in another thread, so there a problem how should i do it ? I have a special area for drawing - QLabel. I've tried to do it through QPixmap in main thread and everything is fine, but when I try to do it through signal/slot in another thread no image appear :(

Actually, when I transform my coordinates into GUI-coordinates they become fractional so I don't know how to paint them, because drawLine functions has integer argument: (int x1, int y1, int x2, int y2).

This is how i create another thread (I need to run only one function, so it is the best way i think) QtConcurrent::run(this,&MainWindow::parseXML)

Hope you will help me, because I will become mad %)

P.S I've read that QPixmap is not supported in multi-threading drawing. So now i have no idea how to do that.
QPainter can be used in a thread to paint onto QImage, QPrinter, and QPicture paint devices. Painting onto QPixmaps and QWidgets is not supported. On Mac OS X the automatic progress dialog will not be displayed if you are printing from outside the GUI thread.


Solution

  • You are apparently looking for a QGraphicsView (or preferably QQuickView if you care about performance and are working with Qt5). That's the solution which Qt offers for exactly this purpose.

    To your question -- there is no way in Qt to do the painting in a separate thread; any widget class cannot be touched from another thread. The proposed invokeMethod call is actually an asynchronous callback which gets queued for execution in the main thread. You could generate a QImage, pass it to the GUI thread and let the GUI use it, but I'd seriously suggest working with the scene graph (the QGraphicsView) because it was designed and optimized for precisely this purpose.