Skip to content
Advertisement

PySide2 Custom Signal Error: “AttributeError: ‘function’ object has no attribute ‘connect'”

This is my third project using PySide and I came across an unusual error when trying to use custom Signals and Slots. Below is a variation of what I am working on that is giving me the AttributeError. I have used a similar syntax for other projects with no issues, so any help is appreciated. I do understand per the error that I am trying to connect a function to a slot, however if I use the @Signal decorator I receive a separate error basically saying that I cannot use it.

from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
import sys


class TestSignal(QObject):
    signal = Signal(float)

    def __init__(self):
        QObject.__init__(self)

    def changed(self, test_value: float):
        self.signal.emit(test_value)


class Main(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.signal = TestSignal()
        self.signal.changed.connect(self.test_slot) # this is where the error occurs
    
        self.central_widget = QWidget()

        self.go_button = QPushButton("Emit")
        self.go_button.clicked.connect(self.emit_signal)

        self.change_label = QLabel("Push Button")

        self.test_layout = QVBoxLayout()
        self.test_layout.addWidget(self.change_label)
        self.test_layout.addWidget(self.go_button)
        self.setCentralWidget(self.central_widget)

        self.central_widget.setLayout(self.test_layout)

        self.show()

    @Slot(float)
    def test_slot(self, test_value):
        self.change_label.setText("Emitted Signal successcully")

    def emit_signal(self):
        self.signal.changed()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Main()

    app.exec_()
    sys.exit(0)

Advertisement

Answer

The signal is called “signal”, “changed” is just a method where the signal is emitted. Recommendation: Use more descriptive names to avoid this type of confusion

class TestSignal(QObject):
    signal = Signal(float)

    def changed(self, test_value: float):
        self.signal.emit(test_value)


class Main(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.signal = TestSignal()
        self.signal.signal.connect(self.test_slot)
    
        self.central_widget = QWidget()

        self.go_button = QPushButton("Emit")
        self.go_button.clicked.connect(self.emit_signal)

        self.change_label = QLabel("Push Button")

        self.test_layout = QVBoxLayout()
        self.test_layout.addWidget(self.change_label)
        self.test_layout.addWidget(self.go_button)
        self.setCentralWidget(self.central_widget)

        self.central_widget.setLayout(self.test_layout)

        self.show()

    @Slot(float)
    def test_slot(self, test_value):
        self.change_label.setText("Emitted Signal successcully {}".format(test_value))

    def emit_signal(self):
        self.signal.changed(5.0)
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement