1. 程式人生 > >PyQt5學習筆記16----PyQt訊號和槽傳遞額外引數

PyQt5學習筆記16----PyQt訊號和槽傳遞額外引數

使用Pyqt程式設計過程中,經常會遇到給槽函式傳遞額外引數的情況。但是訊號-槽機制只是指定訊號如何連線到槽,訊號定義的引數被傳遞給槽,而額外的引數(使用者定義)不能直接傳遞。

而傳遞額外引數又是很有用處。你可能使用一個槽處理多個元件的訊號,有時要傳遞額外的資訊。

一種方法是使用lambda表示式。

  1. from PyQt4.QtCore import *  
  2. from PyQt4.QtGui import *  
  3. class MyForm(QMainWindow):  
  4.     def __init__(self, parent=None):  
  5.         super(MyForm, self
    ).__init__(parent)  
  6.         button1 = QPushButton('Button 1')  
  7.         button2 = QPushButton('Button 1')  
  8.         button1.clicked.connect(lambdaself.on_button(1))  
  9.         button2.clicked.connect(lambdaself.on_button(2))  
  10.         layout = QHBoxLayout()  
  11.         layout.addWidget(button1)  
  12.         layout.addWidget(button2)  
  13.         main_frame = QWidget()  
  14.         main_frame.setLayout(layout)  
  15.         self.setCentralWidget(main_frame)  
  16.     def on_button(self, n):  
  17.         print('Button {0} clicked'.format(n))  
  18. if __name__ == "__main__":  
  19.     import sys  
  20.     app = QApplication(sys.argv)  
  21.     form = MyForm()  
  22.     form.show()  
  23.     app.exec_()  


解釋一下,on_button是怎樣處理從兩個按鈕傳來的訊號。我們使用lambda傳遞按鈕數字給槽,也可以傳遞任何其他東西---甚至是按鈕元件本身(假如,槽打算把傳遞訊號的按鈕修改為不可用)

第2個方法是使用functools裡的partial函式。

  1. button1.clicked.connect(partial(self.on_button, 1))  
  2. 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. class Bu1(QWidget):  
  6.     def __init__(self, parent=None):  
  7.         super(Bu1, self).__init__(parent)  
  8.         #水平盒式佈局
  9.         layout = QHBoxLayout()  
  10.         #顯示
  11.         self.lbl = QLabel('no button is pressed')  
  12.         #迴圈5個按鈕
  13.         for i in range(5):  
  14.             but = QPushButton(str(i))  
  15.             layout.addWidget(but)  
  16.             #訊號和槽連線
  17.             but.clicked.connect(self.cliked)  
  18.         #使用封裝,lambda
  19.         but = QPushButton('5')  
  20.         layout.addWidget(but)  
  21.         but.clicked.connect(lambdaself.on_click('5'))  
  22.         #使用個who變數,結果不正常,顯示 False is pressed
  23.         #but.clicked.connect(lambda who="5": self.on_click(who))
  24.         #使用封裝,partial函式
  25.         but = QPushButton('6')  
  26.         layout.addWidget(but)  
  27.         but.clicked.connect(partial(self.on_click, '6'))  
  28.         layout.addWidget(self.lbl)  
  29.         #設定佈局
  30.         self.setLayout(layout)  
  31.     #傳遞額外引數   
  32.     def cliked(self):  
  33.         bu = self.sender()  
  34.         if isinstance(bu, QPushButton):  
  35.             self.lbl.setText('%s is pressed' % bu.text())  
  36.         else:  
  37.             self.lbl.setText('no effect')  
  38.     def on_click(self, n):  
  39.         self.lbl.setText('%s is pressed' % n)  
  40. if __name__ == '__main__':          
  41.     app = QApplication(sys.argv)  
  42.     bu =Bu1()  
  43.     bu.show()  
  44.     app.exec_()