pythonqtpython-multithreadingsignals-slotsqmainwindow

How to catch a Signal from QMainWindow class by another thread on PySide?


I have a MainWindow class which have a Gui application running on it and i want that every time i click on a button from my application a signal is emitted and caught by another thread. There is my example code (sorry for not posting my real code but it is real big now):

from PySide.QtGui import *
from PySide.QtCore import *
import sys
import mainGui    #Gui file

class MainWindow(QMainWindow, mainGui.Ui_MainWindow):

mySignal = Signal()


    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.newThread = workThread()
        self.newThread.start()

        #myButton is part of Gui application
        self.myButton.clicked.connect(self.myfunction)

    def myfunction(self):
        self.mySignal.emit()

    (...) #Other functions and methods

class workThread(QThread):
     def __init__(self, parent=None):
         super(workThread, self).__init__(parent)

         #The problem:
         MainWindow.mySignal.connect(self.printMessage)

     def run(self):
          (...)

     def printMessage(self):
         print("Signal Recived")
         (...)


def main():
    app = QApplication(sys.argv)
    form = MainWindow()
    form.show()
    app.exec_()

if __name__=="__main__":
    main()

... and i get the following error: MainWindow.mySignal.connect(self.printMessage) AttributeError: 'PySide.QtCore.Signal' object has no attribute 'connect'

There is any ideia how can i solve this? Thanks in advance!


Solution

  • Signals are just like methods - they must be bound to instances. They won't work correctly if you try to access them directly via the class.

    One way to fix the example is to pass the instance of MainWindow in as the parent of the thread, like so:

        self.newThread = workThread(self)
        ...
    
        parent.mySignal.connect(self.printMessage)