1. 程式人生 > >PyQt 訊號和槽傳遞額外引數

PyQt 訊號和槽傳遞額外引數

使用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))  

《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_()