Pause and Continue a Thread?
-
This post is deleted!
-
When you start a
QThread
it will run its own event loop.doStuff
is the first slot that is executed in that event loop. However, by your design, the while-loop will block the event loop of this thread. The stop signal will thus never be executed asstop
will be executed in the context of the receiver, i.e. the event loop of that other thread and not the main event loop.Here are a few ideas how you could solve your problem:
- Have the
stop_action
connect to a slot inMainWindow
that directly callsself.worker.stop()
. This will be executed in the main event loop, so blocking in the other thread is not a problem. Someone might mention thatWorker.stopped
is not an atomic variable. As long as you don't want to have an immediate reaction this will not be a problem. The worker thread will pick up the change eventually. (Actually, you might even not notice any delay.) - If you want to simulate an infinite loop inside the event loop of that thread, you can have a
QTimer
running with a timeout of 0s. This will constantly put a call to the same slot into your event loop. Still, the stop signal has a chance to slip in between and you'll have a chance to kill that timer. - As you said before you want to send data to the worker thread through a signal-slot connection. This approach would be the preferred way. Only do work in the worker thread when you have new data. Just call a slot in the worker thread (through a signal) with the new data and do the work. Afterwards the worker thread can idle to wait for new data. No need to have a loop running.
- Have the
-
Hi,
Can you show the code you are using to setup doStuff and stop ?
-
This post is deleted!
-
This post is deleted!
@Thomas-Stein How did you connect button signal to stop() method? I think you need to use direct connection in this case as your worker thread does not have running/non blocked event loop.
-
@Thomas-Stein How did you connect button signal to stop() method? I think you need to use direct connection in this case as your worker thread does not have running/non blocked event loop.
This post is deleted! -
This post is deleted!
-
This post is deleted!
Acquire an empty semaphore to pause, and release it to unpause. Use a direct connection to the resume slot when you do. I don't do python, but you could easily transform the following c++ snippet I hope:
class Worker : public QObject { public slots: void pause(); void resume(); private: QSemaphore semaphore; }; void Worker::pause() //< Qt::AutoConnection to pause in the worker thread { semaphore.acquire(); } void Worker::resume() { semaphore.release() //< Qt::DirectConnection to resume }
Matching
pause
->resume
pairs are required for this to run correctly (i.e. to have the next pause actually pause).EDIT: Disregard the above, has nothing to do with the problem as I've not read the whole original post
If you're going to block the event loop there's no reason to actually use the worker object. If you want an endless loop, use a
QTimer
with 0 interval, and stop it whenever you want to pause. -
When you start a
QThread
it will run its own event loop.doStuff
is the first slot that is executed in that event loop. However, by your design, the while-loop will block the event loop of this thread. The stop signal will thus never be executed asstop
will be executed in the context of the receiver, i.e. the event loop of that other thread and not the main event loop.Here are a few ideas how you could solve your problem:
- Have the
stop_action
connect to a slot inMainWindow
that directly callsself.worker.stop()
. This will be executed in the main event loop, so blocking in the other thread is not a problem. Someone might mention thatWorker.stopped
is not an atomic variable. As long as you don't want to have an immediate reaction this will not be a problem. The worker thread will pick up the change eventually. (Actually, you might even not notice any delay.) - If you want to simulate an infinite loop inside the event loop of that thread, you can have a
QTimer
running with a timeout of 0s. This will constantly put a call to the same slot into your event loop. Still, the stop signal has a chance to slip in between and you'll have a chance to kill that timer. - As you said before you want to send data to the worker thread through a signal-slot connection. This approach would be the preferred way. Only do work in the worker thread when you have new data. Just call a slot in the worker thread (through a signal) with the new data and do the work. Afterwards the worker thread can idle to wait for new data. No need to have a loop running.
- Have the