“曲工厂”获梅鹤资本领投数百万元天使轮融资
06-17
自定义信号自定义信号的场景在之前的文章:PySide6 GUI编程(三):信号与槽机制中已经讨论过。在一些需要更大灵活性的场景中,我们需要定制信号来触发更多定制的行为。
示例代码 代码语言:python 代码运行次数:0 Copy Cloud Studio 代码 run from __future__ import comments from PySide6.QtCore import QObject, Signaldef show_signal_parameters(*args): if len(args) == 0: print('发送的参数信号为空') return if len(args) != 1: print('信号发送的参数个数错误') return print('信号发送的参数:', args[0])class MySignals(QObject): """ Signal 只能在继承自 QObject 的类中使用。这是因为 Signal 和 Slot 机制是 Qt 的核心功能,而该功能是通过 QObject 类实现的。
""" my_signal_1 = Signal (str) my_signal_2 = 信号(int) my_signal_3 = 信号(浮点) my_signal_4 = 信号(bool) my_signal_5 = 信号(列表) my_signal_6 = 信号(dict) my_signal_7 = 信号(元组) my_signal_8 = 信号(设置) my_signal_9 = 信号(对象) ) def __init__(self): super(). __init__() self.my_signal_1.connect(show_signal_parameters) self.my_signal_2.connect(show_signal_parameters) self.my_signal_3.connect(show_signal_parameters) self.my_signal_4.connect(show_signal_parameters) self.my_signal_5.connect(show_signal_parameters) self.my_signal_6.connect(show_signal_parameters) self.my_signal_7.connect(show_signal_parameters) self.my_signal_8.connect(show_signal_parameters) self.my_signal_9.connect(show_signal) _参数) self.my_signal_1.emit('1') self.my_signal_2.emit(2) self.my_signal_3.emit(3.) self.my_signal_4.emit(4) self.my_signal_5.emit([5, ]) self.my_signal_6 。发出({'6': 6}) self.my_signal_7.emit((7,)) self.my_signal_8.emit({8, }) self.my_signal_9.emit([9, '9', ])if __name__ = = '__main__': MySignals() 操作效果 自定义信号和信号参数 使用匿名函数拦截信号 在标准 PySide6 信号中,信号和槽函数的输入参数始终是固定的,虽然这可以在普通信号中使用带来方便,但它也限制了一些更灵活的用途,例如按钮点击行为。
当我想要获取更多信息时,标准的信号和槽函数无法满足要求,所以需要拦截原生信号。 ,并对信号参数进行重新处理或打包,传递给自定义函数进行处理。
示例代码 代码语言:python 代码运行时间:3 Copy Cloud Studio 代码 run from __future__ import comments from datetime import datetime from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidgetdef on_button_clicked(clicked: bool): """ 标准槽函数 ,仅接收 clicked: bool 参数 """ print('Button was clicked (standard slot function on_button_clicked):', clicked, datetime.now().isoformat())def on_button_clicked_2(clicked: bool, button: QPushButton): " ""自定义中间槽函数接收clicked:bool和button:QPushButton参数,clicked:bool是按钮点击时发送的参数,是标准槽函数参数,中间槽函数会额外接收button:QPushButton参数。 """ print( '按钮被单击(中间槽函数 on_button_clicked_2):', clicked, button.text(), datetime.now().isoformat())# def on_button_clicked_4(clicked: bool, button: QPushButton ):# print('按钮被 Click (中间槽函数 on_button_clicked_4, 与 functools.partial 结合使用):', clicked, button.text(),# datetime.now().isoformat())class MyWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle('信号拦截及信号参数修改') button1 = QPushButton('测试按钮1(标准槽函数)') button1.setCheckable(True ) # 设置为checkable,这样槽函数中接收的参数为True Button1.clicked.connect(on_button_clicked) button2 = QPushButton('测试按钮2(lambda表达式作为中间槽函数)') button2.setCheckable(True) #使用lambda表达式作为中间槽函数button2.clicked.connect(lambda button_clicked: on_button_clicked_2(clicked = button_clicked, button = button2)) button3 = QPushButton('测试按钮3(纯lambda表达式槽函数)') button3.setCheckable( True) # 使用lambda表达式作为中间槽函数 # button=button3 是一个默认参数 # 它的值在定义lambda函数时就确定了 # 因此,即使在调用槽函数时button变量的值发生了变化,它也会被传递给槽函数button参数的值仍然是定义lambda函数时的值button3.clicked.connect( lambda clicked, button = button3: print('Button was clicked (纯lambda表达式槽函数):',clicked,button.text(),datetime.now().isoformat())) #button4 = QPushButton('测试按钮4(functools.partial方法会报错)') #button4.setCheckable(True) # # functools .partial 可以生成一个与原函数行为相同的新函数,但有些参数有预设值 # # 当前场景中,当信号连接到槽函数时,我们使用 functools.partial 来创建一个新函数, # # 它将button作为预设参数传递给on_button_clicked # # 但在当前场景下,使用functools.partial的方法不适用,因为预设参数会放在其他参数之前,导致有一个参数传递问题 # # 运行时会报错: TypeError: on_button_clicked_4() miss 1 requiredpositional argument: 'clicked' # new_func = functools.partial(on_button_clicked_4, button = button4) # button4.clicked.connect(new_func) v_main_layout = QVBoxLayout () v_main_layout.addWidget(button1) v_main_layout.addWidget(button2) v_main_layout.addWidget(button3) # v_main_layout.addWidget(button4) 容器 =QWidget() container.setLayout(v_main_layout) self.setCentralWidget(container)if ??__name__ == '__main__': app = QApplication() ins = MyWindow() ins.show() app.exec() 匿名函数参数示例运行基于Lambda槽函数进行信号拦截的效果。
使用匿名函数时的陷阱。匿名函数中的变量引用问题是一个非常常见的陷阱。
尤其是在循环中使用匿名函数时,很容易形成一些错觉。示例代码 代码语言:python 代码运行时间:0 Copy Cloud Studio 代码运行 from __future__ import comments from PySide6.QtGui import QFontfrom PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidgetclass MyMainWindow(QMainWindow): def __init__(self ) : super().__init__() self.setWindowTitle('在 lambda 槽函数中使用参数值传递的示例') v_main_layout = QVBoxLayout() for i in range(10): button = QPushButton(str(i),parent = self ) # 由于 lambda 函数没有自己的 i 变量 # 它将捕获外部作用域中对 i 的引用 # 这意味着当单击按钮时 # self.button_clicked_1 方法将在最后收到 i 的值循环的 # 改为创建按钮时的值 button.clicked.connect(lambda clicked: self.button_clicked_1(i)) # 默认参数值 = i 用于捕获当前 i 值 # 由于对默认参数进行求值当定义 lambda 函数时 # 它将在每次循环迭代中捕获 i 的当前值 # 这样,当单击按钮时, self.button_clicked_2 方法将收到正确的值 # 即与按钮 button.clicked 关联的值.connect(lambda 点击, value = i: self.button_clicked_2(value)) # 使用闭包保证每个按钮的点击事件都能正确传递其对应的i值 button.clicked.connect(self.create_click_handler(i)) v_main_layout.addWidget(button ) self.label_1 = QLabel('label_1') self.label_1.setFont(QFont('UbuntuMono NF', 20)) self.label_2 = QLabel('label_2') self.label_2.setFont(QFont('UbuntuMono NF', 20)) self .label_3 = QLabel('label_3') self.label_3.setFont(QFont('UbuntuMono NF', 20)) v_main_layout.addWidget(QLabel('-' * 16)) v_main_layout.addWidget(self.label_1) v_main_layout.addWidget( QLabel('-' * 16)) v_main_layout.addWidget(self.label_2) v_main_layout.addWidget(QLabel('-' * 16)) v_main_layout.addWidget(self.label_3) 容器 = QWidget() 容器.setLayout (v_main_layout) self .setCentralWidget(容器)def button_clicked_1(self, value: int): self.label_1.setText('button_clicked_1, value={}'.format(str(value))) def button_clicked_2(self, value: int): self.label_2.setText(' button_clicked_2, value={}'.format(str(value))) # 闭包 def create_click_handler(self, value: int): def on_click(_: bool): self.label_3.setText('button_clicked_3, value={} ' .format(str(value))) return on_clickif __name__ == '__main__': app = QApplication() ins = MyMainWindow() ins.show() app.exec() 的核心逻辑也可以通过闭包来避免引用。
问题在于运行效果错误的lambda参数引用是通过匿名函数设置槽函数的默认参数。在匿名函数的基础上,我们可以对槽函数进行更多的修改。
设置默认功能是修改项目之一。
版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
标签:
相关文章
06-17
06-17
06-06
06-18
06-17
最新文章
【玩转GPU】ControlNet初学者生存指南
【实战】获取小程序中用户的城市信息(附源码)
包雪雪简单介绍Vue.js:开学
Go进阶:使用Gin框架简单实现服务端渲染
线程池介绍及实际案例分享
JMeter 注释 18 - JMeter 常用配置组件介绍
基于Sentry的大数据权限解决方案
【云+社区年度征文集】GPE监控介绍及使用