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

2023-11-16

信号与槽的参数

上节介绍了信号与槽的基本使用方法,本节介绍其参数传递的情况。通过为槽函数传递特定的参数,可以实现更复杂的功能。既可以传递 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)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

86-信号和槽-信号与槽的参数 的相关文章

  • 在 Windows 上将 Mercurial (hg) 存储库转换为 Git (7)

    我现在真的很沮丧 我有一个现有的 hg 存储库 其中有几个月的编码历史 我想将其放入私有 Github 存储库中 以便我可以从那里对其进行处理 不幸的是我使用的是 Windows 我似乎找不到any转换我实际上可以正常工作的存储库的方法 实
  • R 脚本自动化时的不同结果

    以下命令对 pdf 文件执行 Ghostscript 这pdf file变量包含该 pdf 的路径 bbox lt system paste C gs gs8 64 bin gswin32c exe sDEVICE bbox dNOPAUS
  • 为什么 cygwin 无法读取我的主目录中的 .ssh/config 文件?

    我正在使用 cygwin 并且正在尝试设置 ssh config 文件 Cygwin 的文件夹位于我的 C 驱动器中 我的主目录是 C Users USER 我注意到 当我编辑 C Users USER ssh config 时 cygwi
  • 如何让脚本执行结束后自动删除?

    是否可以制作一个Python脚本 在Windows中执行结束时删除 py文件 自删除 这种方式使您的程序不依赖于操作系统 from os import remove from sys import argv remove argv 0 奖励
  • 嵌入清单文件以要求具有 mingw32 的管理员执行级别

    我正在 ubuntu 下使用 i586 mingw32msvc 交叉编译应用程序 我很难理解如何嵌入清单文件以要求 mingw32 具有管理员执行级别 对于我的例子 我使用了这个hello c int main return 0 这个资源文
  • 了解 Qt3D 创建的网格

    我创建了一个 Qt3D 网格 如下所示 Qt3DCore QEntity newEntity new Qt3DCore QEntity Qt3DExtras QConeMesh mesh new Qt3DExtras QConeMesh m
  • PyQt4 信号和槽

    我正在使用 PyQt4 编写我的第一个 Python 应用程序 我有一个 MainWindow 和一个 Dialog 类 它是 MainWindow 类的一部分 self loginDialog LoginDialog 我使用插槽和信号 这
  • 如何解决内存碎片

    我们偶尔会遇到这样的问题 长时间运行的服务器进程 在 Windows Server 2003 上运行 由于内存分配失败而引发异常 我们怀疑这些分配由于内存碎片而失败 因此 我们一直在寻找一些可能对我们有帮助的替代内存分配机制 我希望有人能告
  • 由于图形处理单元配置,不支持 Windows Phone 模拟器(Mac 上的 Windows 7)

    启动 Windows Phone 模拟器时出现错误 不支持 Windows Phone 模拟器 因为您的计算机没有所需的图形处理单元配置 如果没有图形处理单元 XNA 框架页面将无法运行 您想继续启动模拟器吗 当我尝试访问网页 任何网页 时
  • QFileSystemModel setRootPath

    我正在尝试创建一个 Qt 应用程序来显示文件夹 Mac OS 中的 Users 文件夹 的内容 这是代码 QFileSystemModel dirModel new QFileSystemModel dirModel gt setRootP
  • 从命令行运行 R 代码 (Windows)

    我在名为 analysis r 的文件中有一些 R 代码 我希望能够从命令行 CMD 运行该文件中的代码 而无需通过 R 终端 并且我还希望能够传递参数并在我的代码中使用这些参数 例如就像下面的伪代码 C gt execute r scri
  • 设置 Form.KeyPreview = true 的缺点?

    我想知道 Form KeyPreview 属性实际上有什么用处 它为什么存在以及将其设置为 true 会带来什么 风险 我想它一定有some负面影响 否则它根本不应该存在 或者至少默认情况下是正确的 EDIT 我很清楚what确实如此 我问
  • QML 列表视图拖放

    我想创建两个 qml 列表视图 可以执行两个功能 拖放一个列表中的项目以更改项目的顺序 跨列表拖放项目 项目将从一个列表中删除并添加到另一个列表中 根据 Qt 文档中的拖放示例 我决定创建两个访问同一列表模型的列表视图 列表模型中的每个项目
  • 在 Cygwin 软件包列表中找不到 Openssl

    这里说的是https github com joyent node wiki Building node js on Cygwin Windows https github com joyent node wiki Building nod
  • 如何从Windows阻止社交媒体[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我想根据时间阻止我的电脑上的社交媒体 晚上 9 点后屏蔽 上午 11 点后解锁 如家长控制 我尝试过关注但失败了 创建了
  • 为什么我只能用管理员权限才能导入Python中的某些模块?

    我正在努力解决 Python 2 7 中的一些奇怪问题 我写了一个很长的工具 在其中导入不同的模块 我必须首先使用它安装pip 该工具将在公司内部共享 不同的用户在其特定机器上拥有不同的权限 当另一个用户登录我的计算机 我在那里拥有管理员权
  • 对于多重继承,使用隐式转换而不是 QueryInterface() 是否合法?

    假设我有一个类实现两个或多个 COM 接口 正如here https stackoverflow com questions 1742848 why exactly do i need an explicit upcast when imp
  • 如何为最终用户方便地启动Java GUI程序

    用户想要从以下位置启动 Java GUI 应用程序Windows 以及一些额外的 JVM 参数 例如 javaw Djava util logging config file logging properties jar MyGUI jar
  • 将 CrashDumps 转储到应用程序运行所在的同一文件夹中

    我编写了一个应用程序 我希望对其进行一定程度的自动调试 我想使用 Windows 错误报告将故障转储输出到应用程序运行所在的同一文件夹中 我的想法是 我可以让我的应用程序在它自己的文件夹中查找任何 dmp 文件 然后根据需要上传它们进行分析
  • 为什么 QT 设计器重新调整大小或不允许我缩小或展开小部件或按钮?

    很多时候 在使用 QT 设计器时 我发现自己需要通过缩小或扩展来调整事物的大小 每当我尝试这样做时 程序都不允许我这样做 而只是恢复到将对象放置在窗口中时给我的原始默认大小 无论我的布局如何 为什么要这样做 是否有可能改变这一点 以便我可以

随机推荐

  • FPGA学习日记(五)ZYNQ——在线逻辑分析仪(ILA)硬件调试及simulator仿真软件的创建使用

    一 在线逻辑分析仪 ILA vivado的在线逻辑分析仪 ILA 其借用了传统逻辑分析仪的理念以及大部分的功能 并利用 FPGA 中的逻辑资源 将这些功能植入到 FPGA 的设计当中 如下图所示 ILA占用一部分FPGA内部逻辑资源 可看做
  • 运算放大器的关键指标详解二(噪声)

    1 噪声指标 Noise 一个正常工作的放大电路 当输入端接地时 用示波器观察输出 你看到的可能不是平直的细线 而是在一定幅度之内的杂乱无章的波形 这就是噪声 你在示波器上看到线越粗 就说明噪声幅度越大 放大电路的输出端噪声 小至 V 以下
  • redis客户端Jedis和Lettuce

    Jedis和Lettuce的区别 Jedis是同步的 不支持异步 Jedis客户端实例不是线程安全的 需要每个线程一个Jedis实例 所以一般通过连接池来使用Jedis Lettuce是基于Netty框架的事件驱动的Redis客户端 其方法
  • 12、剪绳子——剑指offer——动态规划

    剪绳子 问题描述 给你一根长度为n的绳子 请把绳子剪成m段 m和n都是整数 n gt 1并且m gt 1 每段绳子的长度记为k 0 k 1 k m 请问k 0 k 1 k m 可能的最大乘积是多少 首先本题可以用贪婪算法和动态规划算法求解
  • VLC在Android中的使用以及vlc中options的参数

    options 中的参数 我在csdn中找过很多篇文章了 有的文章一个参数也没写 有的写的都是关于缓存的 还有的写了几个 也没说明是什么意思 然后只能跑到csdn下载文档查看 为了方便网友们的使用 这里就简单写一下我是怎么使用的 后面会附上
  • Flink-cdc 同步mysql数据

    下载地址 https github com ververica flink cdc connectors releases 这里下载2 2 0版本 https github com ververica flink cdc connector
  • 搭建RocketMq(超详细,图文并茂)

    环境 jdk 1 8 rocketMq 版本 4 5 1 rocketmq all 4 5 1 bin release zip 附上链接 小伙伴自行下载 链接 https pan baidu com s 1zyzF3uZ3YN0YWzcLt
  • Linux脚本练习之script092- 判断输入的是否为IP地址

    script092 题目 注 题目来源于 SHELL16 判断输入的是否为IP地址 写一个脚本统计文件nowcoder txt中的每一行是否是正确的IP地址 如果是正确的IP地址输出 yes 如果是错误的IP地址 四段号码的话输出 no 否
  • SPECjbb 分析与使用

    SPECjbb 分析与使用 一 目的 二 SPECjbb 简介 2 1 是什么 2 2 三层客户 服务器模型结构 2 3 特性 三 环境说明 四 TPC C 简介 4 1 是什么 4 2 TPC C模型 4 3 TPC C指标 4 4 TP
  • dword ptr指令讲解

    dword ptr指令讲解 8086CPU的指令 可以处理两种尺寸的数据 byte和word 所以在机器指令中要指明 指令进行的是字操作还是字节操作 对于这个问题 汇编语言中用一下方法处理 1 通过寄存器名指明要处理的数据的尺寸 例如 下面
  • linux配置交换内存(虚拟内存)

    虚拟内存 Virtual Memory 是操作系统内存管理的一种技术 它将主存虚拟化 使得程序可以获得更大的可用内存空间 虚拟内存的主要优点有 提高内存利用率 可以加载更大的程序到内存中执行 提供了内存保护 避免程序间相互干扰 实现了懒加载
  • 【FPGA多周期约束】

    多周期约束及语法 一 什么时候需要用到多周期约束 Vivado TimeQuest等时序引擎默认是按照单周期关系分析数据关系的 即数据在发起沿发送 在捕获被捕获 发起沿和捕获沿相差一个周期 但是很多情况是 数据路径逻辑较为复杂 导致延时较大
  • 朴素贝叶斯基本原理和预测过程、先验概率、后验概率、似然概率概念

    贝叶斯原理是英国数学家托马斯 贝叶斯提出的 贝叶斯原理 建立在主观判断的基础上 在我们不了解所有客观事实的情况下 同样可以先估计一个值 然后根据实际结果不断进行修正 举例 一个袋子里有10个球 其中6个黑球 4个白球 那么随机抓一个黑球的概
  • 关于电商秒杀系统中防超卖、以及高性能下单的处理方案简述

    秒杀抢购系统的成功平稳运行 有一些需要注意的知识点 1 高并发 以及刷接口等黑客请求对服务端的负载冲击 2 高并发时带来的超卖 即商品数量的控制 3 高负载下 下单的速度和成功率的保证 4 其他 以秒杀单品为例 如抢小米手机 解决方案探讨
  • 大型网站架构核心要素之可用性:高可用架构

    前言 上节我们讲了网站核心要素之性能 这节我们接着讲第二个核心要素可用性 网站的可用性 描述的是一个网站是否可以正常使用的特性 这个特性是比较关键的 直接影响公司形象和利益 因此也有很多大公司把这点作为技术人员的绩效考核之一 既然那么重要
  • Springboot毕设项目地铁站自动售票系统77x9w(java+VUE+Mybatis+Maven+Mysql)

    项目运行 环境配置 Jdk1 8 Tomcat8 5 Mysql HBuilderX Webstorm也行 Eclispe IntelliJ IDEA Eclispe MyEclispe Sts都支持 项目技术 Springboot myb
  • Plotly Express 详细使用指南,20组案例从入门到进阶(附源代码)

    作者 阳哥 出品 Python数据之道 ID PyDataLab 大家好 我是阳哥 今天跟大家分享的是 Plotly Express 的详细使用教程 Plotly Express 是 Python 交互式可视化库 Plotly 的高级组件
  • 【Deepin-15.11】下【Datax】使用【插件】进行【csv文件读写】

    接上 1 将Downloads目录下的压缩包放到指定文件夹下 题目要求 2 按照要求创建文件夹 题目要求 3 Github Datax txtfilereader模板官网将模板copy下来 写入文本文档并修改后缀名 复制到job 题目指定
  • Android Studio 中如何添加ViewModelProviders依赖?

    我的做法是在class类中直接导入文件 import androidx lifecycle ViewModelProvidels 一个小白 就当是记录一下啦
  • 86-信号和槽-信号与槽的参数

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