自動關聯的槽函數
pyqt5由ui轉化成的py文件中,在setup函數下最后一行為
QtCore.QMetaObject.connectSlotsByName(Form)
這個函數使用了Qt的元對象(QMetaObject),會搜索窗體中的從屬組件,將匹配的信號和槽函數關聯起來
他假設的槽函數名稱是
on_<object name>_<signal name>(<signal parameters>)
這個函數的作用是為自帶的一些內建函數編寫槽函數,在designer中綁定的信號,如clicked在命名時不需要在函數中進行綁定,如
def on_chkBoxBold_toggled(self,checked): ## "Bold" 復選框
font=self.ui.textEdit.font()
font.setBold(checked) #參數 checked 表示勾選狀態
self.ui.textEdit.setFont(font)
按鈕chkBOxBold會自動綁定,不需要執行connect。
overload型信號處理
@pyqtSlot修飾符的作用
說明函數的參數類型 ,以使信號和槽正確關聯
有一些信號是重載的信號,如clicked()和clicked(bool),在使用帶有參數的信號時無法直接自動關聯,需要進行指定,因為
默認是自動關聯無參數的信號的,此時需要使用@pyqtSlot修飾符,將函數的參數類型聲明清楚.
對於非默認的 overload 型信號,槽函數必須使用修飾符@pyqtSlot 聲明函數參數類型。如果兩種參數
的 overload 型信號都要關聯槽函數,那么兩個槽函數名必須不同名,且在關聯時要做設置.
@pyqtSlot(bool) ##修飾符指定參數類型,用於 overload 型的信號
def on_chkBoxItalic_clicked(self,checked):
font=self.ui.textEdit.font()
font.setItalic(checked)
self.ui.textEdit.setFont(font)
自定義信號與槽
- 使用PyQt5.QtCore.pyqtSignal()為一個類定義新的信號
- 定義信號時,類必須是 QObject 類的子類。
- 信號需定義為類屬性,這樣定義的信號是未綁定的,在創建類的實例后,pyqt5會自動將類的實例與信號綁定。
一個綁定的型號有connect(),disconnect(),emit()三個函數
pyqtSignal()的句法是:
pyqtSignal(types[, name[, revision=0[, arguments=[]]]])
自定義信號與槽的演示
## 自定義信號與槽的演示
import sys
from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal
class Human(QObject):
## 定義一個帶 str 類型參數的信號
nameChanged = pyqtSignal(str)
## overload 型信號有兩種參數,一種是 int,另一種是 str
ageChanged = pyqtSignal([int],[str])
def __init__(self,name='Mike',age=10,parent=None):
super().__init__(parent)
self.setAge(age)
self.setName(name)
def setAge(self,age):
self.__age= age
self.ageChanged.emit(self.__age) #發射 int 參數信號
if age<=10:
ageInfo="你是 少年"
elif (10< age <=18):
ageInfo="你是 青年"
else:
ageInfo="你成年了"
self.ageChanged[str].emit(ageInfo) #發射 str 參數信號
def setName(self,name):
self.__name = name
self.nameChanged.emit(self.__name)
class Responsor(QObject):
@pyqtSlot(int)
def do_ageChanged_int(self,age):
print("你的年齡是: "+str(age))
@pyqtSlot(str)
def do_ageChanged_str(self,ageInfo):
print(ageInfo)
## @pyqtSlot(str)
def do_nameChanged(self, name):
print("Hello,"+name)
if __name__ == "__main__": ##測試程序
print("**創建對象時**")
boy=Human("Boy",16)
resp=Responsor()
boy.nameChanged.connect(resp.do_nameChanged)
## overload 的信號,兩個槽函數不能同名,關聯時需要給信號加參數區分
boy.ageChanged.connect(resp.do_ageChanged_int) #默認參數, int 型
boy.ageChanged[str].connect(resp.do_ageChanged_str) #str 型參數
print("\n **建立關聯后**")
boy.setAge(35) #發射兩個 ageChanged 信號
boy.setName("Jack") #發射 nameChanged 信號
boy.ageChanged[str].disconnect(resp.do_ageChanged_str) #斷開關聯
print("\n **斷開 ageChanged[str]的關聯后**")
boy.setAge(10) #發射兩個 ageChanged 信號
Human類
其中ageChanged具有兩種類型的overload信號,信號的參數類型可以是int也可以是str。
對於overload型信號,定義時第一個位置的參數是默認參數,不需要注明參數,如
boy.ageChanged.connect(resp.do_ageChanged_int) #默認參數, int 型
在關聯非默認參數時,就需注明參數,如
boy.ageChanged[str].connect(resp.do_ageChanged_str) #str 型參數
通過信號的emit()函數發射信號,在類的某個狀態發生變化需要通知外部時,發射相應的信號。
如果信號關聯了一個槽函數就會執行槽函數,沒有關聯就不會有任何動作。
Responsor類
定義了三個函數,與Human類實例對象的信號建立關聯。
信號ageChanged有兩種參數類型,要與兩種參數的ageChange建立關聯,兩個槽函數名稱必須不同,所以為
- do_ageChanged_int
- do_ageChanged_str