[PyQt] Waiting For A Signal
Giuseppe Corbelli
giuseppe.corbelli at copanitalia.com
Wed May 21 16:03:46 BST 2014
On 20/05/2014 19:30, Robert Kent wrote:
> Hi All,
>
> As the subject line of suggests, I want to wait for a signal to be emitted
> (block essentially), but I want to do this whilst keeping the GUI alive. I
> have tried both creating my own event loop and re-implelmenting libqxt's
> QxtSignalWaiter, but my signal of choice is never caught until after either
> the event loop has quit of the signal waiter has stopped waiting. I'm guessing
> this is something to do with the way the event loop is executed in PyQt (or
> I'm doing something very wrong ;o). Has anyone had any success or experience
> with doing this in Python (I've done it before in C++).
Well, I don't have a solution but just more questions. In single thread mode
the dispatching and timing seems to be unreliable, while with the second
thread everything seems fine. I don't see where the error lies...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import logging
from PyQt4 import QtCore
class Waiter(QtCore.QObject):
def __init__(self):
super(Waiter, self).__init__()
self.timeout = False
self.timerID = None
self.signal_received = False
def anyslot(self, *args, **kwargs):
logging.debug("Signal received")
self.signal_received = True
self.killTimer(self.timerID)
def wait(self, signal, timeout):
signal.connect(self.anyslot)
self.timerID = self.startTimer(timeout)
logging.debug("Processing loop")
while not self.timeout and not self.signal_received:
QtCore.QCoreApplication.instance().processEvents(QtCore.QEventLoop.WaitForMoreEvents)
logging.debug("Processing loop done")
signal.disconnect(self.anyslot)
return self.signal_received
def timerEvent(self, event):
logging.debug("Timeout event")
self.timeout = True
self.killTimer(event.timerId())
class Emitter(QtCore.QObject):
mysignal = QtCore.pyqtSignal()
mysignal2 = QtCore.pyqtSignal()
def __init__(self):
super(Emitter, self).__init__()
self.timer = QtCore.QTimer()
self.timer.setSingleShot(True)
self.timer.setInterval(500)
self.timer.timeout.connect(self.emit2)
def emit(self):
logging.debug("emit")
self.mysignal.emit()
self.timer.start()
def emit2(self):
logging.debug("emit2")
self.mysignal2.emit()
self.timer.stop()
class Receiver(QtCore.QObject):
def __init__(self, emitter):
super(Receiver, self).__init__
self.emitter = emitter
emitter.mysignal.connect(self.slot1)
def slot1(self):
logging.debug("Waiting")
Waiter().wait(self.emitter.mysignal2, 1500)
logging.debug("Wait done")
if __name__ == '__main__':
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG,
format="%(asctime)s.%(msecs)03d|%(levelname)-8s|%(name)s|%(filename)s:%(lineno)d|%(message)s")
app = QtCore.QCoreApplication(sys.argv)
#~ thr = QtCore.QThread()
#~ thr.start()
emitter = Emitter()
receiver = Receiver(emitter)
#~ emitter.moveToThread(thr)
timer = QtCore.QTimer()
timer.timeout.connect(emitter.emit)
timer.start(1000)
sys.exit(app.exec_())
--
Giuseppe Corbelli
WASP Software Engineer, Copan Italia S.p.A
Phone: +390303666318 Fax: +390302659932
E-mail: giuseppe.corbelli at copanitalia.com
More information about the PyQt
mailing list