PyQt5學習筆記16----PyQt訊號和槽傳遞額外引數
阿新 • • 發佈:2019-01-10
使用Pyqt程式設計過程中,經常會遇到給槽函式傳遞額外引數的情況。但是訊號-槽機制只是指定訊號如何連線到槽,訊號定義的引數被傳遞給槽,而額外的引數(使用者定義)不能直接傳遞。
而傳遞額外引數又是很有用處。你可能使用一個槽處理多個元件的訊號,有時要傳遞額外的資訊。
一種方法是使用lambda表示式。
- from PyQt4.QtCore import *
- from PyQt4.QtGui import *
- class MyForm(QMainWindow):
- def __init__(self, parent=None):
-
super(MyForm, self
- 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')
- #迴圈5個按鈕
- for i in range(5):
- but = QPushButton(str(i))
- layout.addWidget(but)
- #訊號和槽連線
- but.clicked.connect(self.cliked)
- #使用封裝,lambda
- but = QPushButton('5')
- layout.addWidget(but)
- but.clicked.connect(lambda: self.on_click('5'))
- #使用個who變數,結果不正常,顯示 False is pressed
- #but.clicked.connect(lambda who="5": self.on_click(who))
- #使用封裝,partial函式
- 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_()