日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Python Qt GUI设计:信号与槽的使用方法(基础篇—7)

發(fā)布時(shí)間:2023/11/27 生活经验 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python Qt GUI设计:信号与槽的使用方法(基础篇—7) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

1、信號(hào)與槽的概念

2、信號(hào)與槽的基礎(chǔ)函數(shù)

2.1、創(chuàng)建信號(hào)函數(shù)

2.2、連接信號(hào)函數(shù)

2.3、斷開信號(hào)函數(shù)

2.4、發(fā)射信號(hào)函數(shù)

3、信號(hào)和槽的使用方法

3.1、內(nèi)置信號(hào)與槽的使用

3.2、自定義信號(hào)與槽的使用

3.2.1、定義信號(hào)

3.2.2、定義槽函數(shù)

3.2.3、連接信號(hào)與槽函數(shù)

3.2.4、發(fā)射信號(hào)

3.2.5、實(shí)例


1、信號(hào)與槽的概念

信號(hào)(signal)和槽(slot)是Qt的核心機(jī)制,也是在PyQt編程中對(duì)象之間進(jìn)行通信的機(jī)制。在創(chuàng)建事件循環(huán)之后,通過建立信號(hào)和槽的連接就可以實(shí)現(xiàn)對(duì)象之間的通信。當(dāng)信號(hào)發(fā)射(emit)時(shí),連接的槽函數(shù)將會(huì)自動(dòng)執(zhí)行。

信號(hào)(signal)是在特定情況下被發(fā)射(emit)的一種通告。GUI程序設(shè)計(jì)的主要內(nèi)容就是對(duì)界面上各組件發(fā)射的特定信號(hào)進(jìn)行響應(yīng),只需要知道什么情況下發(fā)射了哪些信號(hào),然后合理地去響應(yīng)和處理這些信號(hào)就可以了。

槽(slot)實(shí)質(zhì)上是一個(gè)函數(shù),可以被直接調(diào)用,是對(duì)信號(hào)響應(yīng)的函數(shù)。槽函數(shù)與一般的函數(shù)不同的是:槽函數(shù)可以與一個(gè)信號(hào)關(guān)聯(lián),當(dāng)信號(hào)被發(fā)射時(shí),關(guān)聯(lián)的槽函數(shù)會(huì)被自動(dòng)執(zhí)行。

在Qt編程中,通過Qt信號(hào)和槽機(jī)制對(duì)鼠標(biāo)或鍵盤在界面上的操作進(jìn)行響應(yīng)處理。例如,對(duì)鼠標(biāo)單擊按鈕的執(zhí)行處理信號(hào)的操作。

PyQt的窗口控件類中有很多內(nèi)置信號(hào),開發(fā)者也可以添加自定義信號(hào)。信號(hào)與槽具有如下特點(diǎn):

  • 一個(gè)信號(hào)可以連接多個(gè)槽;
  • 一個(gè)信號(hào)可以連接另一個(gè)信號(hào);
  • 信號(hào)參數(shù)可以是任何Python類型;
  • 一個(gè)槽可以監(jiān)聽多個(gè)信號(hào);
  • 信號(hào)與槽的連接方式可以是同步連接,也可以是異步連接;
  • 信號(hào)與槽的連接可能會(huì)跨線程;
  • 信號(hào)可能會(huì)斷開。

2、信號(hào)與槽的基礎(chǔ)函數(shù)

2.1、創(chuàng)建信號(hào)函數(shù)

本文僅描述主要的信號(hào)函數(shù),具體詳情可參照官方文檔:Support for Signals and Slots — PyQt v5.15 Reference Guide

PyQt的內(nèi)置信號(hào)是自動(dòng)定義的。使用 PyQt5.QtCore.pyqtSignal()函數(shù)可以為QObject創(chuàng)建一個(gè)信號(hào),使用pyqtSingnal()函數(shù)可以把信號(hào)定義為類的屬性。pyqtSignal()函數(shù)信息如下圖所以:

2.2、連接信號(hào)函數(shù)

使用connect()函數(shù)可以把信號(hào)綁定到槽函數(shù)上。connect()函數(shù)信息如下圖所示:

2.3、斷開信號(hào)函數(shù)

使用disconnect()函數(shù)可以解除信號(hào)與槽函數(shù)的綁定。disconnect()函數(shù)信息如下圖所示:

2.4、發(fā)射信號(hào)函數(shù)

使用emit()函數(shù)可以發(fā)射信號(hào)。emit()函數(shù)信息如下圖所示:

3、信號(hào)和槽的使用方法

信號(hào)與槽有三種使用方法,第一種是內(nèi)置信號(hào)與槽的使用,第二種是自定義信號(hào)與槽的使用,第三種是裝飾器的信號(hào)與槽的使用。由于第三種方法本質(zhì)上是第一種方法的衍生,因此這里簡要介紹前兩種方法的使用。

Qt Designer中提供了一些最基礎(chǔ)的信號(hào)和槽設(shè)置方法,在實(shí)際的項(xiàng)目開發(fā)中,信號(hào)和槽最佳的使用方式是Qt Designer和編程相結(jié)合,才能提高開發(fā)效率。

3.1、內(nèi)置信號(hào)與槽的使用

所謂內(nèi)置信號(hào)與槽的使用,是指在發(fā)射信號(hào)時(shí),使用窗口控件的函數(shù),而不是自定義的函數(shù)。在信號(hào)與槽中,可以通過 QObject.signal.connect將一個(gè)QObject的信號(hào)連接到另一個(gè)QObject的槽函數(shù)。

可以在【編輯->Edit Signal/slot】中進(jìn)行信號(hào)和槽設(shè)置。

進(jìn)入信號(hào)槽編輯模式,可以直接在發(fā)射者(“Button"按鈕)上按住鼠標(biāo)左鍵不放,拖動(dòng)到接收者(Form窗體)上,這樣就建立起了連接,如下圖所示:

接著會(huì)彈出“配置連接"對(duì)話框,如下圖所示:

可以看到按鈕控件會(huì)發(fā)射很多內(nèi)置信號(hào)和槽,選擇所需信號(hào),然后單擊“OK"按鈕,就會(huì)生成對(duì)應(yīng)的槽函數(shù)處理。

例如,我想實(shí)現(xiàn)單擊按鈕關(guān)閉窗口的效果,所以這里勾選“顯示從QWidget繼承的信號(hào)和槽"復(fù)選框。

在左側(cè)按鈕的信號(hào)欄里選擇clicked()信號(hào),在右側(cè)的Form槽函數(shù)中選擇close(),這意味著對(duì)按鈕單擊會(huì)發(fā)射clicked信號(hào),這個(gè)信號(hào)會(huì)被Form窗體的槽函數(shù)close()捕捉到,并觸發(fā)該窗體的close行為(也就是關(guān)閉該窗體)。

連接信號(hào)和槽成功后,會(huì)發(fā)現(xiàn)在Edit Signal/slot(編輯信號(hào)/槽)模式下,所創(chuàng)建的信號(hào)和槽關(guān)系的連線是紅色的,如下圖所示:

接著將UI界面轉(zhuǎn)換為Python文件,這里我使用Eric 6編譯,不再贅述,效果如下所示:

拓展學(xué)習(xí):Python Qt GUI設(shè)計(jì):將UI文件轉(zhuǎn)換為Python文件的三種妙招(基礎(chǔ)篇—2)?

UI文件編譯后代碼如下所示:

from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(383, 276)self.pushButton = QtWidgets.QPushButton(Form)self.pushButton.setGeometry(QtCore.QRect(140, 120, 93, 28))self.pushButton.setObjectName("pushButton")self.retranslateUi(Form)self.pushButton.clicked.connect(Form.close)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.pushButton.setText(_translate("Form", "Button"))if __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)Form = QtWidgets.QWidget()ui = Ui_Form()ui.setupUi(Form)Form.show()sys.exit(app.exec_())

代碼中,通過connect函數(shù)連接按鈕的clicked()信號(hào)和槽函數(shù)Form.close(),如下所示:

self.pushButton.clicked.connect(Form.close)

運(yùn)行程序,按鈕是信號(hào)發(fā)射者,當(dāng)單擊按鈕之后會(huì)發(fā)射一個(gè)信號(hào),通過這行代碼程序內(nèi)部的通信機(jī)制知道這個(gè)按鈕的單擊事件被連接到窗體的關(guān)閉事件上,然后通知接收者窗體,可以運(yùn)行槽函數(shù)close(),實(shí)現(xiàn)窗口關(guān)閉。

3.2、自定義信號(hào)與槽的使用

自定義信號(hào)與槽是指在發(fā)射信號(hào)時(shí),不使用窗口控件的函數(shù),而是使用自定義的函數(shù)(簡單地說,就是使用pyqtSignal類實(shí)例發(fā)射信號(hào))。

之所以要使用自定義信號(hào)與槽,是因?yàn)橥ㄟ^內(nèi)置函數(shù)發(fā)射信號(hào)有自身的缺陷,主要是以下三點(diǎn):

  1. 內(nèi)置函數(shù)只包含一些常用的信號(hào),有些信號(hào)的發(fā)射找不到對(duì)應(yīng)的內(nèi)置函數(shù);
  2. 內(nèi)置函數(shù)只有在特定情況下(如按鈕的點(diǎn)擊事件)才能發(fā)射這種信號(hào);
  3. 內(nèi)置函數(shù)傳遞的參數(shù)是特定的,不可以自定義。使用自定義的信號(hào)函數(shù)則沒有這些缺陷。

在PyQt5編程中,自定義信號(hào)與槽的適用范圍很靈活。例如,因?yàn)闃I(yè)務(wù)需求,在程序中的某個(gè)地方需要發(fā)射一個(gè)信號(hào),傳遞多種數(shù)據(jù)類型(實(shí)際上就是傳遞參數(shù)),然后在槽函數(shù)中接收傳遞過來的數(shù)據(jù),這樣就可以非常靈活地實(shí)現(xiàn)一些業(yè)務(wù)邏輯。

自定義信號(hào)的一般流程如下:

  • 定義信號(hào)
  • 定義槽函數(shù)
  • 連接信號(hào)與槽函數(shù)
  • 發(fā)射信號(hào)

3.2.1、定義信號(hào)

使用pyqtSingnal()函數(shù)可以把信號(hào)定義為類的屬性,示例代碼如下所示:

  #無參數(shù)的信號(hào)signal1=pyqtSignal()#帶一個(gè)參數(shù)(整數(shù))的信號(hào)signal2=pyqtSignal(int)#帶兩個(gè)參數(shù)(整數(shù),字符串)的信號(hào)signal3=pyqtSignal(int,str)#帶一個(gè)參數(shù)(列表)的信號(hào)signal4=pyqtSignal(list)#帶一個(gè)參數(shù)(字典)的信號(hào)signal5=pyqtSignal(dict)#帶(整數(shù) 字符串)或者(字符串)的信號(hào)signal6=pyqtSignal([int,str],[str])

3.2.2、定義槽函數(shù)

定義一個(gè)槽函數(shù),它有多個(gè)不同的輸入?yún)⑤敂?shù),示例代碼如下所示:

  def signalCall1( self ):print("signal1 emit")def signalCall2( self,val ):print('signal2 emit,value:',val)def signalCall3( self,val,text ):print('signall3 emit,value:',val,text)def signalCall4( self,val ):print('signal4 emit,value:',val)def signalCall5( self,val ):print('signal5 emit,value',val)def signalCall6( self,val,text ):print('signal6 emit,value',val,text)def signalCall7( self,val ):print('signal6 ovetload emit',val)

3.2.3、連接信號(hào)與槽函數(shù)

使用connect()函數(shù)可以把信號(hào)綁定到槽函數(shù)上,示例代碼如下所示:

    #信號(hào)與槽函數(shù)的鏈接self.signal1.connect(self.signalCall1)self.signal2.connect(self.signalCall2)self.signal3.connect(self.signalCall3)self.signal4.connect(self.signalCall4)self.signal5.connect(self.signalCall5)self.signal6[int,str].connect(self.signalCall6)self.signal6[str].connect(self.signalCall7)

3.2.4、發(fā)射信號(hào)

使用emit()函數(shù)可以發(fā)射信號(hào),示例代碼如下所示:

    #信號(hào)發(fā)射self.signal1.emit()self.signal2.emit(1)self.signal3.emit(1,'第三個(gè)')self.signal4.emit([1,2,3,4])self.signal5.emit({"name":'JIA','age':'21'})self.signal6[int,str].emit(1,"第六")self.signal6[str].emit('第六')

3.2.5、實(shí)例

將上述片段代碼,整合,非常簡單,各位可以看著理解。

from PyQt5.QtCore import QObject,pyqtSignalclass CusSignal(QObject):#無參數(shù)的信號(hào)signal1=pyqtSignal()#帶一個(gè)參數(shù)(整數(shù))的信號(hào)signal2=pyqtSignal(int)#帶兩個(gè)參數(shù)(整數(shù),字符串)的信號(hào)signal3=pyqtSignal(int,str)#帶一個(gè)參數(shù)(列表)的信號(hào)signal4=pyqtSignal(list)#帶一個(gè)參數(shù)(字典)的信號(hào)signal5=pyqtSignal(dict)#帶(整數(shù) 字符串)或者(字符串)的信號(hào)signal6=pyqtSignal([int,str],[str])def __init__(self,parent=None):super(CusSignal, self).__init__(parent)#信號(hào)與槽函數(shù)的鏈接self.signal1.connect(self.signalCall1)self.signal2.connect(self.signalCall2)self.signal3.connect(self.signalCall3)self.signal4.connect(self.signalCall4)self.signal5.connect(self.signalCall5)self.signal6[int,str].connect(self.signalCall6)self.signal6[str].connect(self.signalCall7)#信號(hào)發(fā)射self.signal1.emit()self.signal2.emit(1)self.signal3.emit(1,'第三個(gè)')self.signal4.emit([1,2,3,4])self.signal5.emit({"name":'JIA','age':'21'})self.signal6[int,str].emit(1,"第六")self.signal6[str].emit('第六')#槽函數(shù)def signalCall1( self ):print("signal1 emit")def signalCall2( self,val ):print('signal2 emit,value:',val)def signalCall3( self,val,text ):print('signall3 emit,value:',val,text)def signalCall4( self,val ):print('signal4 emit,value:',val)def signalCall5( self,val ):print('signal5 emit,value',val)def signalCall6( self,val,text ):print('signal6 emit,value',val,text)def signalCall7( self,val ):print('signal6 ovetload emit',val)if __name__ == '__main__':custSignal=CusSignal()

?運(yùn)行效果如下所示:

關(guān)于信號(hào)與槽的使用方法就講到這了,在后面的實(shí)踐中我們?cè)偌?xì)聊,感興趣小伙伴可看看以下的拓展學(xué)習(xí)鏈接~


參考資料、拓展學(xué)習(xí):

《Python QT GUI與數(shù)據(jù)可視化編程》作者:楊海玲責(zé)任編輯 (中國)王維波 栗寶

《PyQt5快速開發(fā)與實(shí)戰(zhàn)》王碩

官方網(wǎng)站:PyQt API中信號(hào)與槽詳細(xì)解釋

Qt for Python 信號(hào)和槽的使用詳解

PyQt中的信號(hào)(signal)和槽(slot)機(jī)制以及Designer中的使用?

Python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽的高級(jí)使用技巧(自定義信號(hào)與槽)詳解與實(shí)例?

總結(jié)

以上是生活随笔為你收集整理的Python Qt GUI设计:信号与槽的使用方法(基础篇—7)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。