在Pyside开发过程中会遇到这么个问题:当多个按钮在很多行中,需要在点击槽函数中确认按钮的行。
普通的按钮点击信号如下:
clicked()
该信号并未有任何参数,无法得到有效的信息,那么如何完成点击哪个确定是哪个按钮呢?
本文将介绍几种方式来实现上面的需求。本文的示例将用下面的界面来举例:
运行画面:
一、自定义按钮(不推荐)
1.1自定义代码
通过自定义按钮控件,可以实现添加一个自定义信号来添加槽函数的参数:
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import QPushButton
from PySide6.QtCore import Signal
class IndexButton(QPushButton):
index_clicked = Signal(int)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.index = 0
def 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_Form
class 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 = i
btn.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_Form
class 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 inner
for 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_Form
class 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_Form
class 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()来获取内容,又不想自定义控件,闭包是不错的选择。