I create a "new QWidget" in a separate thread. When that thread ends, my widget gets deleted. How can I fix this problem?
I create a "new QWidget" in a separate thread. When that thread ends, my widget gets deleted. How can I fix this problem?
Do you actually create a QWidget in another thread? Or was that just a figure of speech?
From "Threading support in Qt":
So, creating widgets outside the GUI thread is out of the question.In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished. This is the approach used for implementing the Mandelbrot and the Blocking Fortune Client example.
What are you trying to do? There must be another solution.
EDIT:
I think a more relevant quote is:
For example, I want to run the following "ChainLink script" in a separate thread:
Qt Code:
tab=QTabWidget; for j=1:10; X=QWidget; addTab(tab,X,'testing '+toString(j)); end;To copy to clipboard, switch view to plain text mode
ChainLink works fine in one thread, but now I want to execute all scripts in a separate thread, so that the main GUI (console) can continue responding. I am running into trouble because the widgets all disappear when the thread ends.
Unfortunately, I am not familiar to ChainLink. How do you run that script? I assume thre must be some kind of interpreter involved...
Yes... I parse the script and create a syntax tree. Then I execute that syntax tree... each function in the tree comes from a plugin library. One of the functions (in a plugin library) looks like this:
Qt Code:
bool QWidget2(QWidgetPtr &ret) { ret->showNormal(); ret->setAttribute(Qt::WA_DeleteOnClose); return true; }To copy to clipboard, switch view to plain text mode
Everything is fine. But, as I said, what if I want to execute the syntax tree in a separate thread... perhaps you have some idea.
Forget about using widgets in worker threads. You'll need to create the widget in the main thread and communicate with it from the other thread using signals and slots or custom events.
Absolutely not... It seems to me that the syntax tree is by design made to not work in other threads.Everything is fine. But, as I said, what if I want to execute the syntax tree in a separate thread... perhaps you have some idea.
I see it as a widget factory. This is common in projects where widgets are created dynamically. But widget creation should never be designed to require another thread.
You should keep the syntax tree in the main thread. How much does it take for it to parse a script and build the widgets?
For example the designer just blocks a bit when loading very complex UI files...
Regards
You can always chop a lengthy process into chunks and execute one chunk at a time and process events in between.
But this means he must modify his ChainLink component, to make it expose smaller steps.
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