转载:fengyu09
环境:python2.7.8 —— pyqt 4.11.1
使用Pyqt编程过程中,经常会遇到给槽函数传递额外参数的情况。但是信号-槽机制只是指定信号如何连接到槽,信号定义的参数被传递给槽,而额外的参数(用户定义)不能直接传递。而传递额外参数又是很有用处。你可能使用一个槽处理多个组件的信号,有时要传递额外的信息。
第1个方法是使用lambda表达式
1 from PyQt4.QtCore import * 2 from PyQt4.QtGui import * 3 4 5 class MyForm(QMainWindow): 6 def __init__(self, parent=None): 7 super(MyForm, self).__init__(parent) 8 button1 = QPushButton('Button 1') 9 button2 = QPushButton('Button 2') 10 button1.clicked.connect(lambda: self.on_button(1)) 11 button2.clicked.connect(lambda: self.on_button(2)) 12 13 layout = QHBoxLayout() 14 layout.addWidget(button1) 15 layout.addWidget(button2) 16 17 main_frame = QWidget() 18 main_frame.setLayout(layout) 19 20 self.setCentralWidget(main_frame) 21 22 def on_button(self, n): 23 print('Button {0} clicked'.format(n)) 24 25 26 if __name__ == "__main__": 27 import sys 28 app = QApplication(sys.argv) 29 form = MyForm() 30 form.show() 31 app.exec_()
解释一下,on_button是怎样处理从两个按钮传来的信号。我们使用lambda传递按钮数字给槽,也可以传递任何其他东西---甚至是按钮组件本身(假如,槽打算把传递信号的按钮修改为不可用)
第2个方法是使用functools里的partial函数。
button1.clicked.connect(partial(self.on_button, 1))
button2.clicked.connect(partial(self.on_button, 2))
哪个办法好一点?这个属于风格的问题。个人观点,喜欢lambda,条理清楚,而且灵活。
《Rapid GUI Program with Python and QT》 P143例子。
1 from PyQt4.QtCore import * 2 from PyQt4.QtGui import * 3 from functools import partial 4 import sys 5 6 7 class Bu1(QWidget): 8 9 def __init__(self, parent=None): 10 super(Bu1, self).__init__(parent) 11 # 水平盒式布局 12 layout = QHBoxLayout() 13 # 显示 14 self.lbl = QLabel('no button is pressed') 15 # 循环5个按钮 16 for i in range(5): 17 but = QPushButton(str(i)) 18 layout.addWidget(but) 19 # 信号和槽连接 20 but.clicked.connect(self.cliked) 21 22 # 使用封装,lambda 23 but = QPushButton('5') 24 layout.addWidget(but) 25 but.clicked.connect(lambda: self.on_click('5')) 26 # 使用个who变量,结果不正常,显示 False is pressed 27 # but.clicked.connect(lambda who="5": self.on_click(who)) 28 29 # 使用封装,partial函数 30 but = QPushButton('6') 31 layout.addWidget(but) 32 but.clicked.connect(partial(self.on_click, '6')) 33 34 layout.addWidget(self.lbl) 35 # 设置布局 36 self.setLayout(layout) 37 38 # 传递额外参数 39 def cliked(self): 40 bu = self.sender() 41 if isinstance(bu, QPushButton): 42 self.lbl.setText('%s is pressed' % bu.text()) 43 else: 44 self.lbl.setText('no effect') 45 46 def on_click(self, n): 47 self.lbl.setText('%s is pressed' % n) 48 49 50 if __name__ == '__main__': 51 app = QApplication(sys.argv) 52 bu = Bu1() 53 bu.show() 54 app.exec_()