Search code examples
pythonqtpyqtqthreademit

Python QT emit SIGNAL is not invoking callback function


I have the following piece of code:

def callback(param):
    print "in callback"

class Test(QThread):
    def __init__(self):
        QThread.__init__(self)
        #QObject.connect(self, SIGNAL("test_signal(PyQt_PyObject)"), callback)
        print "Test constructed"

    def fallback(self, dummy=None):
        print "in fallback"

    def run(self):
        while 1:
            print "Test running"
            self.emit(SIGNAL("test_signal(PyQt_PyObject)"), {'a': 'b'})
            time.sleep(1)

t = None

if __name__ == "__main__":

    t = Test()
    t.start()
    QObject.connect(t, SIGNAL("test_signal(PyQt_PyObject)"), callback)
    while True:
        time.sleep(2)

However, callback(param) is never called, as in, I don't see the "in callback" printed on the console. Can anyone help with this? I've tried different variations of the code (e.g. removing the parameter from test_signal, connecting to self.fallback(), not including any paramters in self.emit (i.e. removing {'a': 'b'})). I must be missing a very simple but fundamental mechanism, but I just can't figure it out.

Thanks in advance!


Solution

  • If you want a thread to use signals you need to start an event loop, the more straightforward way is to start a QApplication:

    from PyQt4.QtGui import QApplication
    from PyQt4.QtCore import *
    import time
    
    @pyqtSlot(dict)
    def callback(param):
        print "in callback"
        print param
    
    class Test(QThread):
    
        mySignal =  pyqtSignal(dict,name="mySignal")
    
        def __init__(self):
            QThread.__init__(self)
    
        def run(self):
            while 1:
                print "Test running"
                self.mySignal.emit({'a': 'b'})
                time.sleep(1)
    
    if __name__ == "__main__":
        t = Test()
        t.start()
        t.mySignal.connect(callback)
        app = QApplication([])
        app.exec_()