PDA

View Full Version : Multithreading application and GUI



Luc4
1st March 2010, 21:26
Hi! I'm trying to write an application where I show thumbnails of files in a directory. I would like, of course, the GUI to be quite responsive while thumbnails are created. Therefore, I wrote a thread which creates thumbnails and adds them to a subclass I made of QGraphicsView. It seems it's behaving quite good, but not entirely as I thought it would.

The strange thing is that, when I run my application, instead of starting to show, one by one, the generated thumbnails, it waits a little bit, and then shows, all together, many thumbnails. After that, again it waits quite some time, and again shows many thumbnails... etc.... I mean that it seems the GUI is not showing thumbnails as soon as the thread gives them, but at certain points, after some are collected.

Is there anyone who can try to guess why? The generating thread has the LowestPriority, so I suppose, when I tell the view to show the images, the GUI should do that immediately having higher priority...

My suspect is that, this line in my generating thread:

graphicsView->addThumbnail(thumbnail);
which adds my thumbnail to the QGraphicsView using the addItem(...) method, is run within my generating thread, and not the main thread (which manages the GUI). Is this correct? But in case this was true, shouldn't it wait until the thumbnail was shown before generating the following thumbnail? Still doesn't explain the result. Any idea?
Thanks for any help!

chaoticbob
2nd March 2010, 00:54
I've written several apps that do something similar - in Qt and before in Wx. I take an approach that is similar to the one that you described with a few differences. In the thread that I'm resizing the image to make it fit for the the QGraphicsView to display - I send a signal everytime I'm doing with an image.

IIRC, I generally just package up the data into a pointer and just send it. In my main thread, I just read the data back out and do the appropriate thing so that QGraphicsView can display it. After that I ask QGraphicsView to refresh itself and maybe the child I just added.

If you don't ask QGraphicsView to refresh, it might just wait until the next time it needs to fresh and does it then. Which might explain why you're seeing them in batches. If you already are doing this, then something else might be going on that's causing it not to update when it should.

Luc4
2nd March 2010, 06:43
I'm suspecting that the way I'm behaving is not correct cause that way I would do GUI-related operations with a non-GUI thread... Anyway, I use, after all addItem a setScene to the itemsBoundingRect to fit the scene to the content. I suppose this should refresh the content immediately after adding each item... Am I wrong?
Thanks for your advices!

chaoticbob
2nd March 2010, 06:54
If you emit a signal from your non-GUI thread and process it in your main thread, where you would do the refresh, I think it should be okay.

From my understanding, yes you should refresh after each item is added if you want to see it immediately. That's how I handle it in my image browser an it seems to work alright.

yodasoda
2nd March 2010, 07:46
Do you really have a GUI-thread? If you didnt moveToThread(this); in your constructor and you instantiated the QThread in the mainthread then it is still the main thread that handles your process.

Luc4
2nd March 2010, 11:18
I solved using a connection and making a correct repaint of the view. Thanks!