How to use QThread in this case
I want to use one QThread to interactively handle user's inputs events (mouse, keyboard, etc..)
The other thread to do things like drawing, moving data between memory and disk, or heavy computation.
Could anyone kind enough to give me some hints?
user input is send via events to widgets, and widgets MUST live in the main thread. You could derive from QApplication and send all user input as custom events to objects inside a thread (or put them to a queue which is handleded in the thread), but widgets always live in the main thread. This also applies to drawing to the widgets. The only thing you can do inside a thread, is drawing inside a pixmap and blit this pixmap then inside the main thread.
Memory operations, computations etc can surely be done inside a thread. I suggest you read "pepes wiki article":http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects on that.
To clarify what Gerolf said, he means that you can only draw into a QImage in a non-gui thread not into QPixmap. QPixmap is tied to the underlying windowing system which in turn ties it to the main GUI thread.
Ups, I always take the wrong one of QPixmap and QImage ... sorry :-)
Qt reference says that QPixmap is intended for off-screen drawing. Can I use QImage for off-screen drawing from non-gui thread?
And if I can use QImage for off-screen drawing as weel as QPixmap the what is the difference? The point is that currently I use QPixmap for off-screen drawing and I'm going to redesign my app to use non-gui thread for drawing. Does it mean that I will need to use QImage instead of QPixmap? Can I be sure that all methods of QPixmap I currently use can be found in QImage? If not - then what is the solution?
Hmm... the documentation is confusing when it describes QPixmap as "off-screen", because you need to convert a QImage into a QPixmap to display it on-screen. Anyway:
- QImage is a "data structure" class -- it is an array of pixels in your program's memory, so you can access a QImage from any thread in your program.
- QPixmap is tied to your OS's windowing system -- its memory is managed by the OS itself, so you can only access a QPixmap from the GUI thread.
Manipulate pixels using a QImage, in a non-GUI thread
Pass the finished QImage into your GUI thread
In the GUI thread, convert the QImage into a QPixmap, and display it
Edit: I also recommend starting a new thread when you have a question
When redesigning my application to use non-gui thread for drawing I realized that I can't use QBrush::setTexture(QPixmap) method any more, since QPixmap can't be used from non-gui thread. Any idea how can I use pattern based brush for non-gui thread drawing?
There's a lot of things you can't do when you draw in any thread other than the main thread. Font rendering will work differently, for example. The QImage you generate could be huge, depending on your scene.
I recommend thinking -twice- three times before outsourcing GUI to another thread.
If you have a performance or responsiveness issue,
Optimize your code as it runs in the GUI thread
Consider using a different GUI engine (e.g. GraphicsView, OpenGL,...)
See what non-GUI-related data preparations you might be able to put into a separate thread. However, even this is going to make your program much more complicated.
Have o look at Qt::BlockingQueuedConnection
[quote author="bjanuario" date="1364813062"]Have o look at Qt::BlockingQueuedConnection[/quote]What do you wish to achieve with a blocking queued connection?
you could use Qt::BlockingQueuedConnection as connection type to stop your worker thread until the user has entered data. Other thread also waits until the user has finished entering data.
[quote author="JKSH" date="1364814197"][quote author="bjanuario" date="1364813062"]Have o look at Qt::BlockingQueuedConnection[/quote]What do you wish to achieve with a blocking queued connection?[/quote]