I would like to know how to pause a QThread and then resume when I get a signal. I have read and know that I can do something like this:
def run(self):
...
self.ready=False
while not self.ready:
self.sleep(1)
...
...
@QtCore.Slot()
def set_ready(self):
self.ready = True
However, what I want to do is avoid the polling in the thread. I don't want to have to set the sleep to a short amount of time and keep checking. I want to go to sleep until I get a signal from my main thread to continue.
What I am doing in my thread is this:
(pseudo code)
with open file:
read a block of data
while data:
sendThread = send the block via UDP
read the next block of data
while not ready or sendThread.isRunning:
sleep(0.1)
In my main thread I have setup a QtNetwork.QUdpSocket
to connect readyRead to a method to handle incoming datagrams and decode them. When it gets the response that I'm waiting for it sends a signal to the set_ready
slot to tell the thread to send another datagram. I don't always know how long it will take for the other system to respond, though I will likely have some long timeout value of 30seconds or so.
Is there a way to interrupt the sleep of the thread? so I could do something like this:
sleep(30)
if not ready:
Timeout occurred stop processing
else:
Continue processing.
You can do this pretty easily using the worker pattern of using
QThreads
. There's an example in theQThread
documentation. The exact code will be a little different depending on whether you're usingPyQt
orPySide
(it looks like you're usingPySide
from your example).One notable issue with
PySide
compared toPyQt
is that they didn't wrapQtCore.Q_ARG
, so inPyQt
, where you could normally useQMetaObject.invokeMethod
to call a slot (with arguments) on theWorker
object from the main thread, you can't do that directly inPySide
and have to create a dummy signal (ie.Main.send_signal
) to connect to the slot on the worker so you can call it from the main thread.