信號和槽關(guān)聯(lián)
????信號(signal)和槽(slot)是Qt的核心機制。在創(chuàng)建事件循環(huán)之后,通過建立信號和槽的連接就可以實現(xiàn)對象之間的通信。當(dāng)信號發(fā)射(emit)時,連接的槽函數(shù)將會自動執(zhí)行。在 PyQt 5中,信號和槽通過QObject.signal.connectQ)連接。
????所有從 QObject類或其子類(如QWidget)派生的類都能夠包含信號和槽。當(dāng)對象改變其狀態(tài)時,信號就由該對象發(fā)射出去。槽用于接收信號,但它們是普通的對象成員函數(shù)。多個信號可以與單個槽進行連接,單個信號也可以與多個槽進行連接??傊盘柡筒蹣?gòu)建了一種強大的控件編程機制。
????在Qt編程中,通過Qt信號槽機制對鼠標(biāo)或鍵盤在界面上的操作進行響應(yīng)處理,例如對鼠標(biāo)單擊按鈕的處理。Qt中的控件能夠發(fā)射什么信號,以及在什么情況下發(fā)射信號,在Qt的文檔中有說明,不同的控件能夠發(fā)射的信號種類和觸發(fā)時機也是不同的。
????那么如何為控件發(fā)射的信號指定對應(yīng)的處理槽函數(shù)呢?一般有三種方法,第一種是在窗口的UI設(shè)計中操作添加信號和槽;第二種是通過代碼連接信號和槽;第三種是通過Eric的“生成對話框代碼”的功能產(chǎn)生信號和槽。
1、簡單入門
????Qt Designer提供了基本的編輯信號槽方法。首先,新建一個模板名為“Widget”的簡單窗口,該窗口文件名為MainWinsignalSlog01.ui。,它要實現(xiàn)的功能是,當(dāng)單擊關(guān)閉按鈕后關(guān)閉窗口。
????在Qt Designer窗口左側(cè)有一個 Buttons欄,找到QPushButton 控件,把它拖到窗體Form中。在屬性編輯器中,找到按鈕對應(yīng)的 text屬性,把屬性值改為“關(guān)閉窗口”,并將objectName屬性值改為“closeWinBtn”,如圖所示。

單擊工具欄上的“編輯信號/槽”(或者通過單擊“Edit”(編輯)菜單→“編輯信號/槽”),進入信號槽編輯模式,可以直接在發(fā)射者(“關(guān)閉窗口”按鈕)上按住鼠標(biāo)左鍵不放,拖動到接收者(Form 窗體)上,這樣就建立起了連接,如圖

可以看到按鈕控件會發(fā)射很多信號,只要選擇一個信號,然后單擊“OK”按鈕,就會生成對應(yīng)的槽函數(shù)對按鈕發(fā)射的該信號進行處理。
由于要達到單擊按鈕關(guān)閉窗口的效果,所以這里勾選“顯示從QWidget繼承的信號和槽”復(fù)選框。在左側(cè)的closeWinBtn 按鈕的信號欄里選擇clicked()信號,在右側(cè)的Form槽函數(shù)中選擇close(),這意味著對“關(guān)閉窗口”按鈕單擊會發(fā)射clicked信號,這個信號會被Form窗體的槽函數(shù)close()捕捉到,并觸發(fā)該窗體的close行為(也就是關(guān)閉該窗體)。
連接信號和槽成功后,會發(fā)現(xiàn)在“編輯信號/槽”模式下,所創(chuàng)建的信號和槽關(guān)系的連線是紅色的,如圖所示。

此時,按esc鍵釋放編輯信號和槽,恢復(fù)原來的狀態(tài)。
將界面轉(zhuǎn)換為python文件,自動生成的代碼如下:
在使用pyuic5命令生成的Python代碼中,是通過如下代碼直接連接closeWinBtn按鈕的 clicked()信號和槽函數(shù)Form.close()的。注意:使用 Q0bject.signal.connect()連接的槽函數(shù)不要加括號,否則會出錯。
注意:通過pyuic5生成的代碼中有這樣一行代碼:QtCore.QMetaObject.connectSlotsByName(closeWinBtn),這行代碼屬于信號與槽的高級應(yīng)用,在這個案例中可有可無,第7章會對其進行重點解讀。
其實現(xiàn)流程是:按鈕是信號發(fā)射者,當(dāng)單擊按鈕之后會發(fā)射一個信號,通過這行代碼程序內(nèi)部的通信機制知道這個按鈕的單擊事件被連接到窗體的關(guān)閉事件上,然后通知接收者窗體,可以運行槽函數(shù)close()。
為了使窗口的顯示和業(yè)務(wù)邏輯分離,再新建一個調(diào)用窗口顯示的文件CallMain WinsignalSlog01.py,其完整代碼如下:
效果顯示如圖:

點擊“關(guān)閉窗口”按鍵,則窗口關(guān)閉。