I have a QThread which does a lot of calculations (it can run for minutes), and at one (and only one) point it requires user input, for example in the form of a yes/no dialog. Of course, no GUI elements can be accessed and no dialogs opened from the thread (a Qt design choice), as it is not the main thread.
Well there are many obvious solutions, but I’m interested in a “recommended” solution, or a “best practice”.
My ideas:
- as there is only one point where input must be read from the GUI, I can have two threads, the second thread being started after the dialog is evaluated. Problem: it makes the code inflexible, what if I have to introduce more dialogs later? Unlikely, but might happen.
- I have only one thread, and I communicate with signals and slots in both directions (I only have experience with signals in the form of “thread to main”, not in the reverse direction). So the thread runs, comes to the point where the user decision must be made, so the thread emits a signal to the main (aka the GUI thread), the main catches it in a slot, creates the dialog, evaluates the result, and emits a signal to the thread. What now? The thread catches the signal in a slot, but how should it affect the
run()method where the calculations are being done? If therun()exits, the thread dies. So I have something like this in myrun()function:while (!can_continue) { sleep(); }and I setcan_continuein the slot where I caught the signal sent form the main. However, I have some doubts about this being the most simple / most elegant solution. Is there a general practice I should know about?
Your problems with second version arises because you are working with Qt thread wrong.
You should create new object
class Worker: public QObjectthat has signals:and slots:
then create
Qthreadthread object, pushWorkerto the thread, connectstartStage1()withstarted()signal of thread, show dialog on signalstage1Finished()and connect dialog-accepted-signal withstartStage2(). Connectstage2Finishedwithexit()slot of thread.Then you will not have to sleep anywhere, all signals processing will go through standard mechanism in
Qthread. Then you just start the thread to start processing and getfinishedsignal on processing finished.While connecting signals to slots, use
Qt::QueuedConnection.