pyside6的信号与槽的简单测试

        首先必须要正确理解signal.connect(slot)的含义,这个语句执行后,会将“connect(slot)”的括号内的函数slot(槽)引用与signal(信号)连接,当signal(信号)emit(发射)后,slot(槽)函数执行。      

场景1:信号不带参数,但是槽函数需要带运行参数:

        这样的需求很常见,例如一个小部件的clicked动作连接不带参数,但是需要槽函数带一些参数,例如把按钮文字改变,诸如此类。

        这个时候,如果像下面的代码就会出错:

from PyQt5.QtCore import QObject, pyqtSignal


class UI(QObject):  # 创建QObject,用来承载和定义信号
    signal1 = pyqtSignal()  # 定义信号

    def __init__(self):
        super().__init__()


def slot(arg1, arg2):
    print("Received objects:", arg1, arg2)


# UI类的实体化
ui = UI()
# 信号的连接
ui.signal1.connect(slot(1, 2))
ui.signal1.emit()  # 发射信号


# 出错信息:
TypeError: argument 1 has unexpected type 'NoneType'

         原因是connect方法中,应该传递函数引用,而不是函数调用结果 。需要注意的是,pyside6运行上述代码并不提示出错,然而,由于并没有正确传递槽函数,实际也是不能正确运行的。

解决方法: 

1、使用lambda函数:

from PySide6.QtCore import QObject, Signal


class UI(QObject):  # 创建QObject,用来承载和定义信号
    signal1 = Signal()  # 定义信号,为了提高灵活性,并没有定义信号的具体数据类型,而是定义为了object

    def __init__(self):
        super().__init__()


# 定义槽函数
def slot(arg1, arg2):
    print("Received objects:", arg1, arg2)


# UI类的实体化
ui = UI()
# 信号的连接
ui.signal1.connect(lambda: slot(1, 2))
# 发射信号
ui.signal1.emit()

2、使用嵌套函数(闭包):

from PyQt5.QtCore import QObject, pyqtSignal


class UI(QObject):  # 创建QObject,用来承载和定义信号
    signal1 = pyqtSignal()  # 定义信号

    def __init__(self):
        super().__init__()


def slot(arg1, arg2):
    def print_arg():
        print("Received objects:", arg1, arg2)
    return print_arg


# UI类的实体化
ui = UI()
# 信号的连接
ui.signal1.connect(slot(1, 2))
ui.signal1.emit()  # 发射信号


这个代码,执行ui.signal1.connect(slot(1, 2))语句的时候将slot(1, 2)也执行了一遍,而slot(1, 2)的执行结果是返回print_arg这个函数,并将这个函数与信号连接。

3、使用partial函数:

from functools import partial

from PyQt5.QtCore import QObject, pyqtSignal


class UI(QObject):  # 创建QObject,用来承载和定义信号
    signal1 = pyqtSignal()  # 定义信号

    def __init__(self):
        super().__init__()


def slot(arg1, arg2):
    def print_arg():
        print("Received objects:", arg1, arg2)
    return print_arg



# UI类的实体化
ui = UI()
# 信号的连接
ui.signal1.connect(partial(slot(1, 2)))
ui.signal1.emit()  # 发射信号


发射和接收参数的数量:

信号定义了2个参数,只发射了1个,出错。

from PySide6.QtCore import QObject, Signal, QCoreApplication
import sys


def handle_signal(arg1, arg2):
    print("Received objects:", arg1, arg2)


class UI(QObject):  # 创建QObject,用来承载和定义信号
    signal1 = Signal(object, object)  # 定义信号,为了提高灵活性,并没有定义信号的具体数据类型,而是定义为了object

    def __init__(self):
        super().__init__()


if __name__ == "__main__":
    app = QCoreApplication(sys.argv)

    ui = UI()

    ui.signal1.connect(handle_signal)    # 信号的连接
    ui.signal1.emit('a')  # 发射信号

    sys.exit(app.exec())
# 出错信息:
TypeError: signal1(PyObject,PyObject) needs 2 argument(s), 1 given!

信号定义了3个参数,发射了3个,只接收2个,可以的。

from PySide6.QtCore import QObject, Signal, QCoreApplication
import sys


def handle_signal(arg1, arg2):
    print("Received objects:", arg1, arg2)


class UI(QObject):  # 创建QObject,用来承载和定义信号
    signal1 = Signal(object, object, object)  # 定义信号,为了提高灵活性,并没有定义信号的具体数据类型,而是定义为了object

    def __init__(self):
        super().__init__()


if __name__ == "__main__":
    app = QCoreApplication(sys.argv)

    ui = UI()

    ui.signal1.connect(handle_signal)    # 信号的连接
    ui.signal1.emit('a', 100.0, 123)  # 发射信号

    sys.exit(app.exec())


# 运行结果:Received objects: a 100.0

总结:发射的参数必须按照信号的定义数量,槽函数接收的参数数量可以比定义的数量少。

可能的应用场景:PLC通信,上位机接收到PLC发送的数据包之后,第一个数据单元可能规定了数据的参数,第二个数据单元可能是数据的具体内容。

demo:

from PySide6.QtCore import QObject, Signal, QCoreApplication
import sys


def analysis_signal(arg1, arg2):   # 解析PLC数据
    print("Received datas:", arg1, "\nLength of datas:", arg2)


def datas_signal(*args):     #  拆包数据
    print("Datas is:", *args[2:])


class UI(QObject):  # 创建QObject,用来承载和定义信号
    signal1 = Signal(object, object, object)  # 定义信号,为了提高灵活性,并没有定义信号的具体数据类型,而是定义为了object

    def __init__(self):
        super().__init__()


if __name__ == "__main__":
    app = QCoreApplication(sys.argv)

    ui = UI()

    ui.signal1.connect(analysis_signal)    # 信号的连接
    ui.signal1.connect(datas_signal)
    datas = ('a1', 5, (0xfe, 100, 200, 200.0, 123))  # 数据包demo,a1的含义:来自PLC1的数据;5:数据长度;(0xfe, 100, 200, 200.0, 123):数据包具体内容。
    ui.signal1.emit(*datas)  # 发射信号

    sys.exit(app.exec())



# 运行结果:
Received datas: a1 
Length of datas: 5
Datas is: (254, 100, 200, 200.0, 123)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深蓝海拓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值