使用Pyqt编程过程中,经常会遇到给槽函数传递额外参数的情况。但是信号-槽机制只是指定信号如何连接到槽,信号定义的参数被传递给槽,而额外的参数(用户定义)不能直接传递。
而传递额外参数又是很有用处。你可能使用一个槽处理多个组件的信号,有时要传递额外的信息。
一种方法是使用lambda表达式。
- from PyQt4.QtCore import *
- from PyQt4.QtGui import *
-
- class MyForm(QMainWindow):
- def __init__(self, parent=None):
- super(MyForm, self).__init__(parent)
- button1 = QPushButton('Button 1')
- button2 = QPushButton('Button 1')
- button1.clicked.connect(lambda: self.on_button(1))
- button2.clicked.connect(lambda: self.on_button(2))
-
- layout = QHBoxLayout()
- layout.addWidget(button1)
- layout.addWidget(button2)
-
- main_frame = QWidget()
- main_frame.setLayout(layout)
-
- self.setCentralWidget(main_frame)
-
- def on_button(self, n):
- print('Button {0} clicked'.format(n))
-
- if __name__ == "__main__":
- import sys
- app = QApplication(sys.argv)
- form = MyForm()
- form.show()
- 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例子。
- from PyQt4.QtCore import *
- from PyQt4.QtGui import *
- from functools import partial
- import sys
-
- class Bu1(QWidget):
-
- def __init__(self, parent=None):
- super(Bu1, self).__init__(parent)
-
- layout = QHBoxLayout()
-
- self.lbl = QLabel('no button is pressed')
-
- for i in range(5):
- but = QPushButton(str(i))
- layout.addWidget(but)
-
- but.clicked.connect(self.cliked)
-
-
- but = QPushButton('5')
- layout.addWidget(but)
- but.clicked.connect(lambda: self.on_click('5'))
-
-
-
-
- but = QPushButton('6')
- layout.addWidget(but)
- but.clicked.connect(partial(self.on_click, '6'))
-
- layout.addWidget(self.lbl)
-
- self.setLayout(layout)
-
-
- def cliked(self):
- bu = self.sender()
- if isinstance(bu, QPushButton):
- self.lbl.setText('%s is pressed' % bu.text())
- else:
- self.lbl.setText('no effect')
- def on_click(self, n):
- self.lbl.setText('%s is pressed' % n)
-
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- bu =Bu1()
- bu.show()
- app.exec_()