Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

'PySide2.QtCore.Signal' object has no attribute 'emit'



  • When I call emit, the interpreter keep telling me emit do not exist

    OS : win10 64bits
    python : 3.7.3(anaconda)
    install by pip : pip install PySide2
    llvm: libclang-release_70-based-windows-mingw_64\libclang

    Source codes to reproduce

    import sys
    
    from PySide2.QtCore import QObject, Signal
    from PySide2.QtGui import QFont
    from PySide2.QtWidgets import QApplication, QPushButton
    
    class someClass(QObject):
        def __init__(self):
            super(someClass, self).__init__()
            
            self.someSignal = Signal()
            try:
                self.someSignal.emit()
            except Exception as e:
                print("__init__:")
                print(e)
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    		
        sc = someClass()
        button = QPushButton(text="Press me if you want to close the server")
        button.resize(640, 480)    
        button.setFont(QFont("Arial", 20, QFont.Bold))
        button.clicked.connect(button.close)
        button.show()
    
        sys.exit(app.exec_())
    

    packages installed by pip

    certifi      2019.3.9
    mkl-fft      1.0.10
    mkl-random   1.0.2
    numpy        1.16.2
    pip          19.0.3
    PySide2      5.12.2
    scikit-learn 0.20.3
    scipy        1.2.1
    setuptools   40.8.0
    shiboken2    5.12.2
    wheel        0.33.1
    wincertstore 0.2
    

    packages installed by anaconda

    # Name                    Version                   Build  Channel
    blas                      1.0                         mkl    anaconda
    ca-certificates           2019.1.23                     0    anaconda
    certifi                   2019.3.9                 py37_0    anaconda
    icc_rt                    2019.0.0             h0cc432a_1    anaconda
    intel-openmp              2019.3                      203    anaconda
    mkl                       2019.3                      203    anaconda
    mkl_fft                   1.0.10           py37h14836fe_0    anaconda
    mkl_random                1.0.2            py37h343c172_0    anaconda
    numpy                     1.16.2           py37h19fb1c0_0    anaconda
    numpy-base                1.16.2           py37hc3f5095_0    anaconda
    openssl                   1.1.1                he774522_0    anaconda
    pip                       19.0.3                   py37_0    anaconda
    pyside2                   5.12.2                   pypi_0    pypi
    python                    3.7.3                h8c8aaf0_0    anaconda
    scikit-learn              0.20.3           py37h343c172_0    anaconda
    scipy                     1.2.1            py37h29ff71c_0    anaconda
    setuptools                40.8.0                   py37_0    anaconda
    shiboken2                 5.12.2                   pypi_0    pypi
    sqlite                    3.27.2               he774522_0    anaconda
    vc                        14.1                 h21ff451_3    anaconda
    vs2015_runtime            15.5.2                        3    anaconda
    wheel                     0.33.1                   py37_0    anaconda
    wincertstore              0.2                      py37_0    anaconda
    

    Edit : Install by Python 3.5.4 got the same issues



  • Workaround found

    import sys
    
    from PySide2.QtCore import QObject, Signal
    from PySide2.QtGui import QFont
    from PySide2.QtWidgets import QApplication, QPushButton
    
    class someClass(QObject):
        class commu(QObject):
            someSignal = Signal()
    
        def __init__(self):
            super(someClass, self).__init__()
            
            cm = self.commu()
            self.someSignal = cm.someSignal
            cm.someSignal.connect(self.print_msg)
            try:
                cm.someSignal.emit()
            except Exception as e:
                print("__init__:")
                print(e)
    			
        def print_msg(self):
            print("lalalu")
    			
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    		
        sc = someClass()
        button = QPushButton(text="Press me if you want to close the server")
        button.resize(640, 480)    
        button.setFont(QFont("Arial", 20, QFont.Bold))
        button.clicked.connect(button.close)
        button.show()
    
        sys.exit(app.exec_())
    

    Awkward, but unless it work.

    My feel about Qt for python, if you want to use Qt, good with c++ and not forced to used python, pick c++ first. Qt written by c++ has better tool chains and easier to use, more natural compare with Qt for python.



  • Your work-around is the long-winded approach. Simply define your signal as a class variable, but connect/reference it as an instance variable. I believe for the signal/slot mechanism to work worrectly the signals and slots MUST be bound to object instances, not static class methods/variables.

    The following works flawlessly in pyqt.

    class something(QObject):
        # class variable
        mySignal = pyqtSignal()
    
        def Connections(self):
            # used as an instance variable here
            self.mySignal.connect(self.someslot)
    
        def DoSomething(self):
            # used as an instance variable here
            self.mySignal.emit()
    


  • pyqt do not equal to pyside2, they are different beast, with different gotcha



  • I suggest reading this wiki <https://wiki.qt.io/Qt_for_Python_Signals_and_Slots>.

    What I wrote above is valid in pyside2 as well: declare signal as class variable in a class derived from QObject, and call it as an instance variable using emit()...with the correction to my initial comment, that apparently slots can be static or global methods.

    cheers



  • @Kent-Dorfman Tried, do not work, the interpreter keep telling me emit do not exist



  • Try this:

    import sys
    
    from PySide2.QtCore import QObject, Signal, Slot
    from PySide2.QtGui import QFont
    from PySide2.QtWidgets import QApplication, QPushButton
    
    class someClass(QObject):
        
        someSignal = Signal()
    
        def __init__(self):
            super(someClass, self).__init__()
            
            self.someSignal.connect(self.print_msg)
            try:
                self.someSignal.emit()
            except Exception as e:
                print("__init__:")
                print(e)
    
        @Slot()			
        def print_msg(self):
            print("lalalu")
    			
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    		
        sc = someClass()
        button = QPushButton(text="Press me if you want to close the server")
        button.resize(640, 480)    
        button.setFont(QFont("Arial", 20, QFont.Bold))
        button.clicked.connect(button.close)
        button.show()
    
        sys.exit(app.exec_())
    
    • Signals have to be class variables to work.
    • You also need to make sure that the __init__ of the QObject is called. This is where pyside does the setup of the signals, trying to use the signal before setup wont work properly.
    • Lastly, make sure you use a Slot decorator on methods you want to connect into the signal system. It will appear to work without the decorator, but you will run into issues with the python class and c++ object lifetimes getting out of sync.


  • @KeirRice If i copy that code and execute it, it immedeatly prints "lalalu". and not on click.


  • Qt Champions 2019

    @Iceflower said in 'PySide2.QtCore.Signal' object has no attribute 'emit':

    it immedeatly prints "lalalu". and not on click

    Yes, because the signal is emited in someClass.init
    The buitton is only there to close the app.
    If you want to print on button click then connect a slot like it is done now for button.close:

    button.clicked.connect(sc.print_msg)
    


  • Im posting this because the replies above are a bit odd to me... This should work >

    from PySide2.QtCore import Signal, QObject
    
    class myTestObject(QObject):
        someSignal = Signal(str)
    
        def __init__(self):
            QObject.__init__(self)  # call to initialize properly
            self.someSignal.connect(self.testSignal)  # test link
            self.someSignal.emit("Wowz")  # test
    
        def testSignal(self, arg):
            print("my signal test from init fire", arg)
    

Log in to reply