pythonmultithreadingpysideqt-signalsqt-slot

PySide Signals not being sent to Slot, from QThread object


I'm working with a multi-threading application, where a worker thread gets created, that emits a signal. After creating the thread, I connect the signal with an object slot, that will perform some action.

The problem, is the object slot, is not called, can someone help to figure out what's wrong with this code ?

import time
from PySide import QtCore
from PySide.QtCore import Slot, Signal


class Worker1(QtCore.QThread):

    task_done_signal = Signal(int)

    def __init__(self):
        super(Worker1, self).__init__()
        self._run = False

    def run(self):
        self._loop()

    def _loop(self):
        count = 0
        while self._run:
            print("running")
            count += 1
            self.task_done_signal.emit(count)

    def start(self):
        self._run = True
        super(Worker1, self).start()

    def stop(self):
        self._run = False


class Worker1Listener(QtCore.QObject):
    def __init__(self):
        super(Worker1Listener, self).__init__()

    @Slot()
    def print_task(self, val):
        print("listener: {}".format(val))


def test_signals_and_threads():

    # create the thread
    worker = Worker1()

    # create the listener
    listener = Worker1Listener()

    # connect the thread signal with the slot
    worker.task_done_signal.connect(listener.print_task)

    worker.start()

    time.sleep(5)

    worker.stop()

    time.sleep(5)


if __name__ == '__main__':
    test_signals_and_threads()

Solution

  • Your code has several errors:


    import sys
    
    from PySide import QtCore
    
    class Worker1(QtCore.QThread):
        task_done_signal = QtCore.Signal(int)
    
        def __init__(self):
            super(Worker1, self).__init__()
            self._run = False
    
        def run(self):
            self._loop()
    
        def _loop(self):
            count = 0
            while self._run:
                print("running")
                count += 1
                self.task_done_signal.emit(count)
                QtCore.QThread.msleep(1)
    
        def start(self):
            self._run = True
            super(Worker1, self).start()
    
        def stop(self):
            self._run = False
    
    
    class Worker1Listener(QtCore.QObject):
        @QtCore.Slot(int)
        def print_task(self, val):
            print("listener: {}".format(val))
    
    def test_signals_and_threads():
        app = QtCore.QCoreApplication(sys.argv)
        # create the thread
        worker = Worker1()
        # create the listener
        listener = Worker1Listener()
    
        # connect the thread signal with the slot
        worker.task_done_signal.connect(listener.print_task, QtCore.Qt.QueuedConnection)
    
        worker.start()
    
        loop = QtCore.QEventLoop()
        QtCore.QTimer.singleShot(5000, loop.quit)
        loop.exec_()
    
        worker.stop()
    
        loop = QtCore.QEventLoop()
        QtCore.QTimer.singleShot(5000, loop.quit)
        loop.exec_()
    
        #sys.exit(app.exec_())
    
    if __name__ == '__main__':
        test_signals_and_threads()