Introduce a,

Signals and slots are the core mechanisms in Qt and the mechanism by which objects in PyQt communicate

In PyQt5, signals and slots are supported by every QObject and all controls in PyQt that inherit from QWidgets

When a signal is emitted, the connection slot function is automatically executed. In PyQT5, the signal and slot are connected by the connect() function.

There are two main types of signals in PYQT5:

  • 1. Built-in signal (refer to each component for details)
  • 2. Custom signals (mainly used for data transmission and window interaction between components)

Two, a brief introduction of the built-in signal

Use the connect() method to bind the signal to the slot function, and use the disconnect() function to unbind the signal to the slot

  • 1. Button click event (example)

    import sys
    from PyQt5.Qt import *
    
    
    class Window(QWidget):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.setWindowTitle('Button event')
            self.resize(500.500)
            self.move(400.200)
            self.btn = QPushButton('button', self)
            self.init_ui()
    
        def init_ui(self):
            self.btn.resize(100.30)
            self.btn.move(100.50)
    
            self.btn.clicked.connect(self.btn_hand)
    
        def btn_hand(self):
            print('Button clicked')
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())
    Copy the code
  • 2. Use lambda functions directly if the connected event wants to pass arguments

    .def init_ui(self):
        self.btn.resize(100.30)
        self.btn.move(100.50)
    
        self.btn.clicked.connect(lambda: self.btn_hand(1))
    
    def btn_hand(self, flag):
        print('Button clicked :{}'.format(flag))
    ...
    Copy the code

Custom signal

  • 1. The most basic signal and slot without parameters

    import sys
    from PyQt5.Qt import *
    
    
    class SignalObj(QObject):
        Class that defines a signal
        # Customize a signal
        sendMsg = pyqtSignal()
    
        def __init__(self):
            super().__init__()
    
        def run(self):
            self.sendMsg.emit()
    
    
    class Window(QWidget):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.setWindowTitle('Custom event')
            self.resize(500.500)
            self.move(400.200)
            self.btn = QPushButton('button', self)
            self.send = SignalObj()
            Associate events with slots
            self.send.sendMsg.connect(self.slot_hand)
            self.init_ui()
    
        def init_ui(self):
            The built-in events in the system connect to the slot function
            self.btn.clicked.connect(self.btn_hand)
    
        def btn_hand(self):
            self.send.run()
    
        @staticmethod
        def slot_hand(a):
            print('I'm a custom slot function.')
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())
    Copy the code
  • 2. Data is emitted from the signal

    import sys
    from PyQt5.Qt import *
    
    
    class SignalObj(QObject):
        Class that defines a signal
        Note that this is where the constraint is defined to send out the parameter type, the following must be consistent
        sendMsg = pyqtSignal(str)
    
        def __init__(self):
            super().__init__()
    
        def run(self):
            self.sendMsg.emit('hello')
    
    
    class Window(QWidget):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.setWindowTitle('Custom event')
            self.resize(500.500)
            self.move(400.200)
            self.btn = QPushButton('button', self)
            self.send = SignalObj()
            Associate events with slots
            self.send.sendMsg.connect(self.slot_hand)
            self.init_ui()
    
        def init_ui(self):
            The built-in events in the system connect to the slot function
            self.btn.clicked.connect(self.btn_hand)
    
        def btn_hand(self):
            self.send.run()
    
        @staticmethod
        def slot_hand(msg):
            print(F 'I am a custom slot function:{msg}')
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())
    Copy the code
  • 3. For events that send many different data types

    import sys
    from PyQt5.Qt import *
    
    
    class SignalObj(QObject):
        Class that defines a signal
        Note that this is where the constraint is defined to send out the parameter type, the following must be consistent
        sendMsg = pyqtSignal([str], [int])
    
        def __init__(self):
            super().__init__()
    
        def run(self):
            self.sendMsg[str].emit('hello')
            self.sendMsg[int].emit(999)
    
    
    class Window(QWidget):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.setWindowTitle('Custom event')
            self.resize(500.500)
            self.move(400.200)
            self.btn = QPushButton('button', self)
            self.send = SignalObj()
            # associate events with slots (where you want to receive events of that data type)
            self.send.sendMsg[int].connect(self.slot_hand)
            self.init_ui()
    
        def init_ui(self):
            The built-in events in the system connect to the slot function
            self.btn.clicked.connect(self.btn_hand)
    
        def btn_hand(self):
            self.send.run()
    
        @staticmethod
        def slot_hand(msg):
            print(F 'I am a custom slot function:{msg}')
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())
    Copy the code

Use decorator signals and slots

  • 1. Use formatting

    @pyQt5.qtCore. pyqtSlot(argument) def on_ sender object name _ Send signal name (self, argument) : passCopy the code
  • 2. Note that two things must be defined to use a decorator

    • QMetaObject.connectSlotsByName(self)
    • Define one for the events you want to bindid(The self. The BTN. SetObjectName (' name '))
  • 3. Common events for buttons

    .class Window(QWidget):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.setWindowTitle('Decorator signals and slots')
            self.resize(500.500)
            self.move(400.200)
            self.btn = QPushButton('button', self)
            self.init_ui()
    
        def init_ui(self):
            self.btn.clicked.connect(self.btn_hand)
            
        @staticmethod
        def btn_hand(a):
            print('Click the button with connect')
    .  
    Copy the code
  • 4. Events after using decorators

    .class Window(QWidget):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.setWindowTitle('Decorator signals and slots')
            self.resize(500.500)
            self.move(400.200)
            self.btn = QPushButton('button', self)
            self.init_ui()
            Use it after the component is loaded
            QMetaObject.connectSlotsByName(self)
    
        def init_ui(self):
    	   # The names defined in this place are used directly below
            self.btn.setObjectName('btn')
    
        @pyqtSlot()
        def on_btn_clicked(self):
            print('Button clicked with decorator')...Copy the code