轉載: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_()