pyqt5-自定義信號與槽


自動關聯的槽函數

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM