乐之之

知而行乐,乐而行之,天道酬勤,学无止境。
如何快速理解信号与槽?

一、信号与槽的定义

(一)定义

  • 信号(Signal)和槽((Slot)是Qt中的核心机制,也是在PyQt编程中对象之间进行通信的机制。在Qt中,每一个QObject对象和 PyQt中所有继承自QWidget的控件(这些都是QObject的子对象)都支持信号与槽机制。当信号发射时,连接的槽函数将会自动执行。在 PyQt 5中信号与槽通过object.signal.connect()方法连接。

(二)特点

1、一个信号可以连接多个槽。

2、一个信号可以连接另一个信号。

3、信号参数可以是任何Python类型。

4、一个槽可以监听多个信号。

5、信号与槽的连接方式可以是同步连接,也可以是异步连接。

6、信号与槽的连接可能会跨线程。

7、信号可以断开。

二、信号与槽函数的四种用法

(一)内置信号和内置槽函数

from PyQt5.QtWidgets import *
import sys

class WinForm(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('内置的信号和内置的槽函数')
        self.resize(300, 50)
        btn = QPushButton('关闭', self)
        btn.clicked.connect(self.close)
        # 发送者btn——>信号clicked——>连接connect——>接收者self——>内置槽函数close


if __name__ == '__main__':
    app = QApplication(sys.argv)
    wind = WinForm()
    wind.show()
    sys.exit(app.exec_())

(二)内置信号和自定义槽函数

from PyQt5.QtWidgets import *
import sys


class WinForm(QWidget):
    def __init__(self, parent=None):
        super(WinForm, self).__init__(parent)
        self.setWindowTitle("内置信号与自定义槽函数示例")
        self.resize(330, 50)
        btn = QPushButton("关闭", self)
        btn.clicked.connect(self.btn_close)

    def btn_close(self):
        # 这里就是自定义槽函数,再调用内置槽函数close
        self.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = WinForm()
    win.show()
    sys.exit(app.exec_())

(三)自定义信号和内置槽函数

from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSignal
import sys


class Winform(QWidget):
    # 自定义信号
    button_clicked_signal = pyqtSignal()

    def __init__(self, parent=None):
        super(Winform, self).__init__(parent)
        self.setWindowTitle("自定义信号与内置槽函数示例")
        self.resize(330, 50)
        btn = QPushButton("关闭", self)
        # 连接自定义的信号函数
        btn.clicked.connect(self.btn_clicked)
        # 接收信号,连接到内置槽函数
        self.button_clicked_signal.connect(self.close)

    # 自定义的信号函数(也是内置信号clicked的槽函数)
    def btn_clicked(self):
        # 发送自定义信号
        self.button_clicked_signal.emit()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Winform()
    win.show()
    sys.exit(app.exec_())

(四)自定义信号和自定义槽函数

from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSignal
import sys


class WinForm(QWidget):
    # 自定义信号
    button_clicked_signal = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.setWindowTitle("自定义信号与槽函数示例")
        self.resize(330, 50)
        btn = QPushButton("关闭", self)
        # 连接自定义信号函数
        btn.clicked.connect(self.btn_clicked)
        # 接收信号,连接到自定义的槽函数
        self.button_clicked_signal.connect(self.btn_close)

    # 自定义的信号函数(作为自定义信号clicked的槽函数)
    def btn_clicked(self):
        # 发送自定义信号
        self.button_clicked_signal.emit()
    # 自定义的槽函数(调用内置槽函数)
    def btn_close(self):
        self.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = WinForm()
    win.show()
    sys.exit(app.exec_())

信号与槽的建立只需要以下四个步骤:

1、定义信号

2、定义槽函数

3、连接信号与槽函数

4、发送信号

三、信号与槽的高级用法

  • 高级用法主要可以进行参数传递
  • 通过信号与槽建立的四个步骤来介绍

(一)定义信号

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import pyqtSignal


class MyWidget(QWidget):
    # 无参信号
    Signal_NoParameters = pyqtSignal()
    # 带一个参数(整数)的信号
    Signal_OneParameter = pyqtSignal(int)
    # 带一个参数(整数或者字符串)的重载版本的信号
    Signal_OneParameter_Overload = pyqtSignal([int], [str])
    # 带两个参数(整数。字符串)的信号
    Signal_TwoParameters = pyqtSignal(int, str)
    # # 带两个参数([整数,整数]或者[整数,字符串])的重载版本的信号
    Signal_TwoParameters_Overload = pyqtSignal([int, int], [int, str])

(二)定义槽函数

  • 定义槽函数,它有多个不同的输入参数
    def setValue_NoParameters(self):
        """无参槽函数"""
        print("""无参槽函数""")

    def setValue_OneParameter(self, nIndex):
        """带一个参数(整数)的槽函数"""
        print("""带一个参数(整数)的槽函数""", nIndex)

    def setValue_OneParameter_String(self, snIndex):
        """带一个参数(字符串)的槽函数"""
        print("""带一个参数(字符串)的槽函数""", snIndex)

    def setValue_TwoParameters(self, x, y):
        """带两个参数(整数,整数)的槽函数"""
        print("""带两个参数(整数,整数)的槽函数""", x, y)

    def setValue_TwoParameters_String(self, x, szY):
        """带两个参数(整数,字符串)的槽函数"""
        print("""带两个参数(整数,字符串)的槽函数""", x, szY)

(三)连接信号与槽函数

		# 连接无参信号
        self.Signal_NoParameters.connect(self.setValue_NoParameters)

        # 连接带一个整数参数的信号
        self.Signal_OneParameter.connect(self.setValue_OneParameter)

        # 连接带一个整数参数,经过重载的信号
        self.Signal_OneParameter_Overload.connect(self.setValue_OneParameter_String)

        # 连接一个信号,有两个整数参数
        self.Signal_TwoParameters.connect(self.setValue_TwoParameters)

        # 连接带两个参数(整数,整数)的重载版本的信号
        self.Signal_TwoParameters_Overload[int, int].connect(self.setValue_TwoParameters)

        # 连接带两个参数(整数,字符串)的重载版本的信号
        self.Signal_TwoParameters_Overload[int, str].connect(self.setValue_TwoParameters_String)

(四)发送信号

    def mousePressEvent(self, event):
        # 发射无参信号
        self.Signal_NoParameters.emit()
        # 发射带一个参数(整数)的信号
        self.Signal_OneParameter.emit(1)
        # 发射带一个参数(整数)的重载版本的信号
        self.Signal_OneParameter_Overload.emit(1)
        # 发射带一个参数(字符串)的重载版本的信号
        self.Signal_OneParameter_Overload.emit('Abc')
        # 发射带两个参数(整数,字符串)的信号
        self.Signal_TwoParameters.emit(1, 'abc')
        # 发射带两个参数(整数,整数)的重载版本的信号
        self.Signal_TwoParameters_Overload.emit(1, 2)
        # 发射带两个参数(整数,字符串)的重载版本的信号
        self.Signal_TwoParameters_Overload.emit(1, 'abc')

(五)完整代码

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import pyqtSignal


class MyWidget(QWidget):
    """------------------一大片信号定义--------------------"""
    # 无参信号
    Signal_NoParameters = pyqtSignal()
    # 带一个参数(整数)的信号
    Signal_OneParameter = pyqtSignal(int)
    # 带一个参数(整数或者字符串)的重载版本的信号
    Signal_OneParameter_Overload = pyqtSignal([int], [str])
    # 带两个参数(整数。字符串)的信号
    Signal_TwoParameters = pyqtSignal(int, str)
    # # 带两个参数([整数,整数]或者[整数,字符串])的重载版本的信号
    Signal_TwoParameters_Overload = pyqtSignal([int, int], [int, str])

    def __init__(self):
        super().__init__()
        
        """------------------一大片信号连接---------------------"""
        # 连接无参信号
        self.Signal_NoParameters.connect(self.setValue_NoParameters)

        # 连接带一个整数参数的信号
        self.Signal_OneParameter.connect(self.setValue_OneParameter)

        # 连接带一个整数参数,经过重载的信号
        self.Signal_OneParameter_Overload.connect(self.setValue_OneParameter_String)

        # 连接一个信号,有两个整数参数
        self.Signal_TwoParameters.connect(self.setValue_TwoParameters)

        # 连接带两个参数(整数,整数)的重载版本的信号
        self.Signal_TwoParameters_Overload[int, int].connect(self.setValue_TwoParameters)

        # 连接带两个参数(整数,字符串)的重载版本的信号
        self.Signal_TwoParameters_Overload[int, str].connect(self.setValue_TwoParameters_String)

    """------------------一大片槽函数---------------------"""
    def setValue_NoParameters(self):
        """无参槽函数"""
        print("""无参槽函数""")

    def setValue_OneParameter(self, nIndex):
        """带一个参数(整数)的槽函数"""
        print("""带一个参数(整数)的槽函数""", nIndex)

    def setValue_OneParameter_String(self, snIndex):
        """带一个参数(字符串)的槽函数"""
        print("""带一个参数(字符串)的槽函数""", snIndex)

    def setValue_TwoParameters(self, x, y):
        """带两个参数(整数,整数)的槽函数"""
        print("""带两个参数(整数,整数)的槽函数""", x, y)

    def setValue_TwoParameters_String(self, x, szY):
        """带两个参数(整数,字符串)的槽函数"""
        print("""带两个参数(整数,字符串)的槽函数""", x, szY)

    """------------------发射信号函数---------------------"""
    def mousePressEvent(self, event):
        # 发射无参信号
        self.Signal_NoParameters.emit()
        # 发射带一个参数(整数)的信号
        self.Signal_OneParameter.emit(1)
        # 发射带一个参数(整数)的重载版本的信号
        self.Signal_OneParameter_Overload.emit(1)
        # 发射带一个参数(字符串)的重载版本的信号
        self.Signal_OneParameter_Overload.emit('Abc')
        # 发射带两个参数(整数,字符串)的信号
        self.Signal_TwoParameters.emit(1, 'abc')
        # 发射带两个参数(整数,整数)的重载版本的信号
        self.Signal_TwoParameters_Overload.emit(1, 2)
        # 发射带两个参数(整数,字符串)的重载版本的信号
        self.Signal_TwoParameters_Overload.emit(1, 'abc')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    widget = MyWidget()
    widget.show()
    sys.exit(app.exec_())
  • 效果

以上总结来自朝兮暮兮的CSDN博客,链接如下:https://blog.csdn.net/alijunshan/article/details/128274278

posted on 2022-12-15 11:54  乐之之  阅读(186)  评论(0编辑  收藏  举报