[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