引言
前面講各種事件響應(yīng)的時(shí)候說(shuō)過(guò)一些關(guān)于信號(hào)與槽的綁定,實(shí)現(xiàn)相關(guān)的事件響應(yīng),但是并沒(méi)有深入跟詳細(xì)的介紹,之前的事件信號(hào)基本上都是QT的build-in信號(hào),響應(yīng)的槽函數(shù)基本上都是用戶自定義的函數(shù),本文將會(huì)詳細(xì)介紹Qt的信號(hào)與槽交流機(jī)制。
元對(duì)象系統(tǒng)
PyQT5中QGUI中當(dāng)用戶改動(dòng)一個(gè)QWidget的狀態(tài)時(shí),可以通過(guò)支持的信號(hào)觸發(fā)相關(guān)的槽函數(shù)完成動(dòng)作交互。其它的GUI庫(kù)多數(shù)都是通過(guò)Callback(回調(diào))實(shí)現(xiàn)消息傳遞與觸發(fā),QT的這種方法在更廣泛的層面是它底層的元數(shù)據(jù)對(duì)象系統(tǒng)(Meta-Object System )。元數(shù)據(jù)對(duì)象系統(tǒng)提供了信號(hào)與槽機(jī)制在不同的對(duì)象內(nèi)容交互數(shù)據(jù)與信息,元數(shù)據(jù)對(duì)象支持信號(hào)與槽機(jī)制主要依賴:
- 所有的QWidget對(duì)象都是QObject類都是元數(shù)據(jù) - C++使用Q_OBJECT宏定義在私有變量中的類才是元數(shù)據(jù) - 元數(shù)據(jù)對(duì)象編譯器會(huì)提供QObject類子類完成必要的代碼實(shí)現(xiàn)元對(duì)象特性
信號(hào)與槽
信號(hào)與槽機(jī)制中在GUI層面的信號(hào)主要是指靠用戶觸發(fā)特定事件產(chǎn)生,所以QWidget對(duì)象不同GUI組件預(yù)定義了大量的內(nèi)置信號(hào),開(kāi)發(fā)者在使用這些QWidget組件時(shí)只要把這些信號(hào)綁定到自定義的槽函數(shù)即可實(shí)現(xiàn)特定事件的響應(yīng)觸發(fā)特定方法。任意一個(gè)綁定信號(hào)的響應(yīng)函數(shù)都可以被稱為槽函數(shù),槽函數(shù)跟信號(hào)是松散耦合的關(guān)系,只有當(dāng)槽函數(shù)被鏈接到特定信號(hào)的時(shí)候它才會(huì)響應(yīng)特定事件。一個(gè)槽函數(shù)可以被鏈接到多個(gè)信號(hào)實(shí)現(xiàn)響應(yīng),同樣一個(gè)信號(hào)可以被不同的槽函數(shù)鏈接。信號(hào)與槽是QT編程架構(gòu)中最重要的組件之一。
信號(hào)
PyQT5中的信號(hào)分為兩種一種是build-in的信號(hào),主要是跟不同QWidget組件產(chǎn)生特定關(guān)聯(lián),比如valueChanged、toggled、clicked等這些信號(hào);另外一類信號(hào)是開(kāi)發(fā)者自定義信號(hào),這些信號(hào)可以幫助開(kāi)發(fā)者實(shí)現(xiàn)數(shù)據(jù)交互、特定界面刷新、在不同線程之間傳遞消息等等。builid-in的信號(hào)不需要開(kāi)發(fā)者激發(fā),開(kāi)發(fā)者只要綁定到特定的槽函數(shù)即可實(shí)現(xiàn)在動(dòng)作響應(yīng)時(shí)自定激發(fā);自定義信號(hào)必須通過(guò)顯式調(diào)用的方式激發(fā):
custom_signal.emit(parameters)
槽函數(shù)
任何一個(gè)正常的函數(shù)都可以成為槽函數(shù),類的實(shí)例方法通過(guò)信號(hào)鏈接成為槽函數(shù)之后被直接調(diào)用而不需要開(kāi)發(fā)者再初始類實(shí)例代碼。相比直接通過(guò)接口回調(diào)的方式,信號(hào)與槽架構(gòu)方式帶來(lái)了很大的靈活性,但是同時(shí)也會(huì)帶來(lái)更多的執(zhí)行調(diào)用時(shí)間,QT官方文檔指出這樣方法相比回調(diào)響應(yīng)過(guò)程會(huì)慢一點(diǎn)。
代碼演示部分
代碼演示部分只演示自定義信號(hào)跟自定義槽函數(shù)是如何工作的,build-in信號(hào)跟自定義槽函數(shù)在之前的文章中實(shí)際已經(jīng)演示了很多次,這里不在重復(fù)代碼演示。
數(shù)據(jù)類含有自定義信號(hào)
1classMyTextData(QtCore.QObject): 2fire_draw_text_signal=QtCore.pyqtSignal(str) 3 4def__init__(self): 5super(MyTextData,self).__init__() 6print("createmytext...") 7self.text_content="OpenCV開(kāi)發(fā)者聯(lián)盟" 8 9deftext_changed(self,text): 10self.text_content=text 11self.fire_draw_text_signal.emit(self.text_content)初始化,綁定自定義信號(hào)與自定義槽函數(shù)
1#初始化自定義數(shù)據(jù)類 2self.my_data=MyTextData() 3self.my_data.fire_draw_text_signal.connect(self.show_text) 4self.my_data.text_changed("自定義信號(hào)演示")自定義槽函數(shù)
1defshow_text(self,text): 2painter=QtGui.QPainter(self.label.pixmap()) 3pen=QtGui.QPen(QtCore.Qt.green) 4painter.setPen(pen) 5font=QtGui.QFont() 6font.setBold(True) 7font.setPointSizeF(24) 8painter.setFont(font) 9painter.drawText(QtCore.QPoint(20,50),"OpenCV演示-"+text) 10painter.end()觸發(fā)與調(diào)用
1defon_update_gray(self): 2image=cv.imread("images/test5.png") 3gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) 4dst=cv.cvtColor(gray,cv.COLOR_GRAY2RGB) 5height,width,channel=dst.shape 6bytesPerLine=3*width 7img=QtGui.QImage(dst.data,width,height,bytesPerLine,QtGui.QImage.Format_RGB888) 8pixmap=QtGui.QPixmap(img) 9pix=pixmap.scaled(QtCore.QSize(620,500),QtCore.Qt.KeepAspectRatio) 10self.label.setPixmap(pix) 11self.my_data.text_changed("圖像灰度化")會(huì)自動(dòng)繪制指定文本到QLabel標(biāo)簽的圖像上,代碼運(yùn)行結(jié)果如下:
審核編輯:劉清
-
GUI
+關(guān)注
關(guān)注
3文章
641瀏覽量
39493 -
回調(diào)函數(shù)
+關(guān)注
關(guān)注
0文章
87瀏覽量
11530 -
pyqt5
+關(guān)注
關(guān)注
0文章
25瀏覽量
3392
原文標(biāo)題:PyQT5開(kāi)發(fā)之自定義信號(hào)與槽函數(shù)詳解
文章出處:【微信號(hào):CVSCHOOL,微信公眾號(hào):OpenCV學(xué)堂】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論