Unsolved How to process events during infinite loop in Worker thread
-
I've created a Worker object in Qt to process video input indefinitely, and then move it into a QThread to keep the UI thread going. The problem is, I designed it such that the video capture function runs in an infinite loop until interrupted by a flag, and the flag was supposed to be set by a slot in the Worker object, but since the Worker object is inside the infinite loop, it never processes this "quit" slot (or at least I think that's what's happening). I depend on an external library so substituting the video polling for another method is not really an option. Can someone please confirm that this is indeed the problem and suggest a solution? Here's the code:
class worker : public QObject{ Q_OBJECT public: worker(QObject* parent = NULL); ~worker(){} Q_SLOT void process(); Q_SLOT void stop(); private: bool quit; }; worker::worker(QObject *parent) : QObject(parent){ quit = false; } void worker::process(){ while(!quit){ //this library call puts the thread to sleep until a frame is available WaitForVideoFrame(); } } void worker::stop(){ quit = true; }
and then from the UI object I have:
MyWorker = new worker(); QThread* thread = new QThread; MyWorker->moveToThread(thread); connect(thread, SIGNAL(started()), MyWorker, SLOT(process())); QPushButton* stop_button = new QPushButton(this); connect(stop_button, SIGNAL(clicked(bool)), MyWorker, SLOT(stop())); thread->start();
The problem here is that when I press the stop_button, nothing happens, the worker keeps running the loop. Is there maybe a function that I can call to yield processing time to the event loop from within the infinite loop? Or a better design/solution for this? Any suggestions are welcome.
-
@armandomartins said in How to process events during infinite loop in Worker thread:
since the Worker object is inside the infinite loop, it never processes this "quit" slot (or at least I think that's what's happening).
Yes, that's exactly what's happening. Event loops (which process signals/slots) and infinite loops are incompatible with each other; you cannot have both in the same thread.
I depend on an external library so substituting the video polling for another method is not really an option. Can someone please confirm that this is indeed the problem and suggest a solution?
In this case:
- Don't use a worker QObject +
moveToThread()
. Instead, subclass QThread and put your infinite loop inside your override ofQThread::run()
. - From the main thread, call
QThread::requestInterruption()
when you want to quit. (You don't need to implement your own Quit function) - Replace
while (!quit) {...}
withwhile (!isInterruptionRequested()) {...}
This should also significantly simplify your code.
See:
- Don't use a worker QObject +