86-信号和槽-信号与槽的参数

信号与槽的参数

上节介绍了信号与槽的基本使用方法,本节介绍其参数传递的情况。通过为槽函数传递特定的参数,可以实现更复杂的功能。既可以传递 Qt 的内置参数,也可以传递自定义参数,当然,内置参数和自定义参数也可以放在一起传递。自定义参数既可以通过 lambda 表达式传递,也可以通过 partial()函数传递。

案例:信号与槽的参数

image-20230325182448112

# -*- coding: utf-8 -*-

'''
    【简介】
	PySide6中 信号与槽 例子,说明参数传递的使用方法
'''

import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import Signal,slot,QMetaObject
from PySide6.QtGui import *
import time
from functools import partial


class SignalslotDemo(QWidget):
    signal1 = Signal()
    signal2 = Signal(str)
    signal3 = Signal(str,int,list,dict)
    signal4 = Signal(str,int,list,dict)

    def __init__(self,*args,**kwargs):
        super(SignalslotDemo,self).__init__(*args,**kwargs)
        self.setWindowTitle('信号与槽案例2-参数传递')
        self.resize(400,300)
        layout = QVBoxLayout()
        self.setLayout(layout)

        self.label = QLabel('用来显示信息',self)
        layout.addWidget(self.label)

        self.button1 = QPushButton("1-内置信号+默认参数",self)
        self.button1.setCheckable(True)
        layout.addWidget(self.button1)
        self.button1.clicked[bool].connect(self.button1Click)

        button2 = QPushButton("2-自定义信号+默认参数",self)
        button2.setCheckable(True)
        self.signal2[str].connect(self.button2Click)
        layout.addWidget(button2)
        button2.clicked.connect(lambda: self.signal2.emit('我是参数'))

        self.button3 = QPushButton("3-内置信号+自定义参数lambda",self)
        self.button3.setCheckable(True)
        layout.addWidget(self.button3)
        self.button3.clicked[bool].connect(lambda bool1: self.button3Click(bool1,button=self.button3,a=5,b='botton3'))

        self.button4 = QPushButton("4-内置信号+自定义参数partial",self)
        self.button4.setCheckable(True)
        layout.addWidget(self.button4)
        self.button4.clicked[bool].connect(partial(self.button4Click,*args,button=self.button4,a=7,b='button4'))

        self.button5 = QPushButton("5-自定义信号+自定义参数lambda",self)
        self.signal3[str,int,list,dict].connect(lambda a1,a2,a3,a4: self.button5Click(a1,a2,a3,a4,button=self.button5,a=7,b='button5'))
        layout.addWidget(self.button5)
        self.button5.clicked.connect(lambda: self.signal3.emit('参数1',2,[1,2,3,4],{'a': 1,'b': 2}))

        self.button6 = QPushButton("6-自定义信号+自定义参数partial",self)
        self.signal4[str,int,list,dict].connect(partial(self.button6Click,*args,button=self.button6,a=7,b='button6'))
        layout.addWidget(self.button6)
        self.button6.clicked.connect(lambda: self.signal4.emit('参数1',2,[1,2,3,4],{'a': 1,'b': 2}))

    def button1Click(self,bool1):
        if bool1 == True:
            self.label.setText("time:%s,触发了'1-内置信号+默认参数',传递一个信号的默认参数:%s',表示该按钮被按下"%(time.strftime('%H:%M:%S'),bool1))
        else:
            self.label.setText("time:%s,触发了'1-内置信号+默认参数',传递一个信号的默认参数:%s',表示该按钮没有被按下"%(time.strftime('%H:%M:%S'),bool1))

    def button2Click(self,_str):
        self.label.setText("time:%s,触发了'2-自定义信号+默认参数',传递一个信号的默认参数:%s'"%(time.strftime('%H:%M:%S'),_str))

    def button3Click(self,bool1,button,a,b):
        if bool1 == True:
            _str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递一个信号的默认参数:{bool1}',表示该按钮被按下。\n三个自定义参数button='{button}',a={a},b='{b}'"
        else:
            _str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递一个信号的默认参数:{bool1}',表示该按钮没有被按下。\n三个自定义参数button='{button}',a={a},b='{b}'"
        self.label.setText(_str)

    def button4Click(self,bool1,button,a,b):
        if bool1 == True:
            _str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递一个信号的默认参数:{bool1}',表示该按钮被按下。\n三个自定义参数button='{button}',a={a},b='{b}'"
        else:
            _str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递一个信号的默认参数:{bool1}',表示该按钮没有被按下。\n三个自定义参数button='{button}',a={a},b='{b}'"
        self.label.setText(_str)

    def button5Click(self,*args,button,a,b):
        _str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递信号的默认参数:{args}',\n三个自定义参数button='{button}',a={a},b='{b}'"
        # print(args,button,a,b)
        self.label.setText(_str)

    def button6Click(self,*args,button,a,b):
        _str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递信号的默认参数:{args}',\n三个自定义参数button='{button}',a={a},b='{b}'"
        # print(args,button,a,b)
        self.label.setText(_str)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = SignalslotDemo()
    demo.show()
    app.exec()

内置信号+默认参数

单击按钮1,self.button1 的按状态会切换,self.label会显示信号触发情况

self.button1 = QPushButton("1-内置信号+默认参数",self)
self.button1.setCheckable(True)
layout.addWidget(self.button1)
self.button1.clicked[bool].connect(self.button1Click)

def button1Click(self,bool1):
    if bool1 == True:
        self.label.setText("time:%s,触发了'1-内置信号+默认参数',传递一个信号的默认参数:%s',表示该按钮被按下"%(time.strftime('%H:%M:%S'),bool1))
    else:
        self.label.setText("time:%s,触发了'1-内置信号+默认参数',传递一个信号的默认参数:%s',表示该按钮没有被按下"%(time.strftime('%H:%M:%S'),bool1))

自定义信号+默认参数

button2 = QPushButton("2-自定义信号+默认参数",self)
button2.setCheckable(True)
self.signal2[str].connect(self.button2Click)
layout.addWidget(button2)
button2.clicked.connect(lambda: self.signal2.emit('我是参数'))

def button2Click(self,_str):
	self.label.setText("time:%s,触发了'2-自定义信号+默认参数',传递一个信号的默认参数:%s'"%(time.strftime('%H:%M:%S'),_str))

内置信号+自定义参数 lambda

在PySide/PyQt编程过程中,经常会遇到为槽函数传递自定义参数的情况,如有一个信号与槽函数的连接如下:

button1.clicked.connect(show_page)

对于 clicked 信号来说,它不能发出参数;对于 show_page()槽函数来说,它需要接收参数,如 show_page()函数可以是这样的:

def show_page(self,name)
	print((name,"单击啦")

于是产生一个问题–信号发出的参数个数为0,槽函数接收的参数个数为 1,由于0<1,因此运行之后一定会报错(这是因为信号发出的参数个数必须大于或等于槽函数接收的参数个数)。

本节通过 lambda 表达式来解决这个问题,下面的章节会介绍通过 functools 中的partial()函数来解决这个问题,通常使用lambda 表达式。详见按钮3,代码如下

self.button3 = QPushButton("3-内置信号+自定义参数lambda",self)
self.button3.setCheckable(True)
layout.addWidget(self.button3)
self.button3.clicked[bool].connect(lambda bool1: self.button3Click(bool1,button=self.button3,a=5,b='botton3'))

def button3Click(self,bool1,button,a,b):
    if bool1 == True:
        _str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递一个信号的默认参数:{bool1}',表示该按钮被按下。\n三个自定义参数button='{button}',a={a},b='{b}'"
    else:
        _str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递一个信号的默认参数:{bool1}',表示该按钮没有被按下。\n三个自定义参数button='{button}',a={a},b='{b}'"
    self.label.setText(_str)

如上述代码所示,可以通过lambda 表达式对 button3Click()函数进行封装,这个函数传送4个参数,分别是内置参数 bool1,以及自定义的3 个参数 button、a、b。内置参数表示接钮接下状态,自定义参数传递额外的信息。

内置信号+自定义参数 partial

使用partial()函数的效果和使用lambda表达式的效果是一样的,这里通过*args捕获内置参数bool,代码如下:

from functools import partial


self.button4 = QPushButton("4-内置信号+自定义参数partial",self)
self.button4.setCheckable(True)
layout.addWidget(self.button4)
self.button4.clicked[bool].connect(partial(self.button4Click,*args,button=self.button4,a=7,b='button4'))

    def button4Click(self,bool1,button,a,b):
		if bool1 == True:
    		_str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递一个信号的默认参数:{bool1}',表示该按钮被按下。\n三个自定义参数button='{button}',a={a},b='{b}'"
		else:
    		_str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递一个信号的默认参数:{bool1}',表示该按钮没有被按下。\n三个自定义参数button='{button}',a={a},b='{b}'"
			self.label.setText(_str)

自定义信号+自定义参数 lambda

为了更好地介绍自定义信号的问题,本节定义了比较复杂的信号,即 signal3=Signal(str,int,list,dict),使用它可以传递多个不同类型的参数,使用方法如下:

signal3 = Signal(str,int,list,dict)


def __init__(self,*args,**kwargs):
    super(SignalslotDemo,self).__init__(*args,**kwargs)
    
    
self.button5 = QPushButton("5-自定义信号+自定义参数lambda",self)
self.signal3[str,int,list,dict].connect(lambda a1,a2,a3,a4: self.button5Click(a1,a2,a3,a4,button=self.button5,a=7,b='button5'))
layout.addWidget(self.button5)
self.button5.clicked.connect(lambda: self.signal3.emit('参数1',2,[1,2,3,4],{'a': 1,'b': 2}))


def button5Click(self,*args,button,a,b):
	_str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递信号的默认参数:{args}',\n三个自定义参数button='{button}',a={a},b='{b}'"
    # print(args,button,a,b)
    self.label.setText(_str)

从上面的代码中可以看出,其使用方法和单一参数的使用方法没有什么不同。

自定义信号+自定义参数 partiall

使用 partial0函数传递多个参数和单个参数没有什么不同,这一点和 lambda 表达式样。partial()函数可以使用*args 捕自定义信号的参数,代码如下:

signal4 = Signal(str,int,list,dict)

def __init__(self,*args,**kwargs):
	super(SignalslotDemo,self).__init__(*args,**kwargs)

    
self.button6 = QPushButton("6-自定义信号+自定义参数partial",self)
self.signal4[str,int,list,dict].connect(partial(self.button6Click,*args,button=self.button6,a=7,b='button6'))
layout.addWidget(self.button6)
self.button6.clicked.connect(lambda: self.signal4.emit('参数1',2,[1,2,3,4],{'a': 1,'b': 2}))


def button6Click(self,*args,button,a,b):
    _str = f"time:{time.strftime('%H:%M:%S')},触发了'{button.text()}',传递信号的默认参数:{args}',\n三个自定义参数button='{button}',a={a},b='{b}'"
    # print(args,button,a,b)
    self.label.setText(_str)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

士别三日,当挖目相待

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

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

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

打赏作者

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

抵扣说明:

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

余额充值