He is the one who wrote ChainLink, so I don't think this will be a problem![]()
He is the one who wrote ChainLink, so I don't think this will be a problem![]()
Thanks for the discussion. I have thought of a solution that I am happy with. Just one more question (see end of post).
ChainLink scripts consist mostly of non-GUI numerical manipulations (like Matlab programs), so they do deserve to be executed in a work thread. However, it is clear based on your comments that creation of widgets within a separate work thread is out of the question. This is a problem since ChainLink has functions to create plots and graphs. Nevertheless, as pointed out in this thread, creating/manipulating widgets does not take much time (as compared with intense numerical computations). Therefore, a hybrid solution should be possible.
So here is what I plan to do:
1. As part of function definition, the user must identify which plugin functions must be executed in the GUI thread.
2. When the work thread encounters a syntax tree node containing a "GUI function", the thread pauses, and a signal is emitted: pleaseExecuteThisNodeInTheGuiThread().
3. When the GUI thread receives this signal, he executes the appropriate node, and sends back a signal: theRequestedNodeHasBeenExecuted(bool success).
4. When the work thread receives this signal, it resumes its work.
Now, my question is: what is the best way for a thread to pause until a signal is received.
Thanks!
Okay I got it working. I used QWaitCondition, and now it works beautifully.
Basically, I execute the syntax tree in a separate thread. Whenever I need to execute a GUI function, I send control back to the main GUI thread using a signal/slot connection, and a QWaitCondition for the response. Now I see how a thread can effectively execute a GUI function in the main thread.
There are two nice possibilities. One is to use custom events instead of signals and use sendEvent() instead of postEvent(). This should make the sending thread block until the event is processed. The other solution is to use blocking signal connections. See the description of QObject::connect() and the description of Qt::BlockingQueuedConnection which you should use. Your code will be much cleaner than when using wait conditions.
magland (7th February 2008)
I am now using Qt::BlockingQueuedConnection as you suggest, and indeed the code is cleaner. Thanks!
There is one thing I am concerned about (although it doesn't seem to be a problem based on some trials). I don't want the thread to resume execution until AFTER the slot has been processed. With Qt::BlockingQueuedConnection, the thread is blocked until the signal is delivered... but is it safe to assume that the slot will be processed before unblocking?
Yes. That's the whole point. At least I think so![]()
Bookmarks