PDA

View Full Version : Crash while using threads



Luc4
17th April 2010, 00:36
Hi! I'm experiencing some crashes that I can't explain. I'm using a QThread to generate previews of images taken from the disk. So, in my GUI thread, I create the new QThread thumbnailLoader, and I start it.

The thumbnailLoader starts by iterating over all the files in the directory and creates the thumbnail with an algorithm I wrote, and then emits a signal imageReady. This signal has been connected before to a method in my GUI thread which sets the new QPixmap to the icon (which is a subclass of QGraphicsItem) which is redrawn with the new icon.

The problem is that I'm experiencing crashes randomly, so I'm trying to figure out why. This is my run() method:


void run() {
// Load the image very quickly.
QPixmap* thumbnail = new QPixmap(...);
emit imageReady(thumbnail);
}

the connected method is instead something like:


void ContentScene::thumbnailGenerated(QPixmap* thumbnail) {
icon->setThumbnail(thumbnail);
}

setThumbnail assigns the pointer to the new pixmap and updated the item. In this situation, do you have any idea of what could be the cause of the crashes? The only thing I could think of is that my thread calls thumbnailGenerated(...) before the previous call was finished. Maybe I should use a semaphore to queue the calls?
Thanks for any advice!

wysota
17th April 2010, 00:39
You can't operate on pixmaps in worker threads. You can only operate on images (QImage, not QPixmap).

Luc4
17th April 2010, 00:48
Oh... this is very interesting... not a problem of semaphores then... Is there any place in the documentation where I can find why this is not possible?
Thank you very much for your help, as usual! :-)

faldzip
17th April 2010, 09:20
From Qt Documentation [Thread-support in Qt modules]:

Painting in Threads

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.

Luc4
17th April 2010, 14:45
Oh, ok, thanks, now I found it. This is quite a problem as I don't know how to avoid having to print to QPixmaps.

The problem is that in my thread I load the images in a Windows HBITMAP, and then I get the QPixmap by using fromWinHBITMAP. I can't emit the signal using the HBITMAP, as I would have to register the HBITMAP, but I'm not sure if I can do that.

So, I thought I could create a QImage instead, but that is not possible as far as I can understand, as I read that creating a QPixmap is required to create the QImage :) and this would result in more overhead I suppose (I need this code to be very efficient). So... this is quite a problem :)

Thank you for your help, and if you had any idea, please suggest! :p Thanks again!

wysota
17th April 2010, 20:19
Oh, ok, thanks, now I found it. This is quite a problem as I don't know how to avoid having to print to QPixmaps.
Use QImage instead, just as I told you.



So, I thought I could create a QImage instead, but that is not possible as far as I can understand, as I read that creating a QPixmap is required to create the QImage
No, that's not true. Even if it was, you could convert a pixmap to QImage in the main thread and then pass it to the worker thread.

Luc4
18th April 2010, 13:19
Yes, I was trying to use QImage, but unfortunately I wasn't able to create the QImage from HBITMAP without using QPixmap :)
Oh, so it was sufficient to create a method in the main thread which performed the conversion?
Anyway, I solved by avoiding completely the use of HBITMAP. I loaded the image into a QImage directly and now I'm not seeing any crash anymore ;)
Thanks!