在Pyside开发过程中会遇到这么个问题:当多个按钮在很多行中,需要在点击槽函数中确认按钮的行。
普通的按钮点击信号如下:
clicked()
该信号并未有任何参数,无法得到有效的信息,那么如何完成点击哪个确定是哪个按钮呢?
本文将介绍几种方式来实现上面的需求。本文的示例将用下面的界面来举例:
运行画面:
一、自定义按钮(不推荐)
1.1自定义代码
通过自定义按钮控件,可以实现添加一个自定义信号来添加槽函数的参数:
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import QPushButton
from PySide6.QtCore import Signalclass IndexButton(QPushButton):index_clicked = Signal(int)def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.index = 0def mousePressEvent(self, event):super().mousePressEvent(event)self.index_clicked.emit(self.index)
1.2Designer中进行提升
如果使用Designer,别忘了还需要进行按钮的提升才可以使用
1.3测试代码
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import QWidget
from UI.TestPage_ui import Ui_Formclass TestPage(QWidget):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.ui = Ui_Form()self.ui.setupUi(self)self.button_list = [self.ui.pushButton_0,self.ui.pushButton_1,self.ui.pushButton_2,self.ui.pushButton_3]for i, btn in enumerate(self.button_list):btn.index = ibtn.index_clicked.connect(self.clicked)def clicked(self, index):self.ui.label.setText(f'当前点击了第{index}个按钮')
二、闭包实现
通过闭包的实现也可以完成相应的功能,闭包可以将临时变量保存到内存中。
2.1代码
def block(func, index):def inner():return func(index)return inner
2.2测试代码
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import QWidget
from UI.TestPage_ui import Ui_Formclass TestPage(QWidget):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.ui = Ui_Form()self.ui.setupUi(self)self.button_list = [self.ui.pushButton_0,self.ui.pushButton_1,self.ui.pushButton_2,self.ui.pushButton_3]def block(func, index):def inner():return func(index)return innerfor i, btn in enumerate(self.button_list):btn.clicked.connect(block(self.clicked, i))def clicked(self, index):self.ui.label.setText(f'当前点击了第{index}个按钮')
三、lambda加闭包实现
lambda加闭包的形式,其实还是一个闭包,但写法上会比普通闭包来的更简洁。
3.1代码
def create_button_callback(index):return lambda: self.clicked(index)
3.2测试代码
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import QWidget
from UI.TestPage_ui import Ui_Formclass TestPage(QWidget):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.ui = Ui_Form()self.ui.setupUi(self)self.button_list = [self.ui.pushButton_0,self.ui.pushButton_1,self.ui.pushButton_2,self.ui.pushButton_3]def create_button_callback(index):return lambda: self.clicked(index)for i, btn in enumerate(self.button_list):btn.clicked.connect(create_button_callback(i))def clicked(self, index):self.ui.label.setText(f'当前点击了第{index}个按钮')
四、self.sender()的使用(推荐)
在发送信号时,self可以拿到相应的发送者,通过它即可获取所对应的按钮,即可通过将按钮进行列表的包裹来判断下标。
4.1代码
index = self.button_list.index(self.sender())
4.2测试代码
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import QWidget
from UI.TestPage_ui import Ui_Formclass TestPage(QWidget):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.ui = Ui_Form()self.ui.setupUi(self)self.button_list = [self.ui.pushButton_0,self.ui.pushButton_1,self.ui.pushButton_2,self.ui.pushButton_3]for i, btn in enumerate(self.button_list):btn.clicked.connect(self.clicked)def clicked(self):index = self.button_list.index(self.sender())self.ui.label.setText(f'当前点击了第{index}个按钮')
五、总结
对于按钮点击时对应按钮的判断是非常常用的功能,由于普通槽函数不带特定参数很难实现相应功能,因此如果比较特殊的参数可以通过自定义控件来完成,如果比较简单如下标即可通过self.sender(),如果无法使用self.sender()来获取内容,又不想自定义控件,闭包是不错的选择。