pyqt5自定義信號(hào)實(shí)例解析
本文研究的主要是pyqt5自定義信號(hào)實(shí)例解析的相關(guān)內(nèi)容,具體介紹如下。
PyQt5已經(jīng)自動(dòng)定義了很多QT內(nèi)建的信號(hào)。但是在實(shí)際的使用中為了靈活使用信號(hào)與槽機(jī)制,我們可以根據(jù)需要自定義signal??梢允褂胮yqtSignal()方法定義新的信號(hào),新的信號(hào)作為類的屬性。
自定義signal說(shuō)明:
pyqtSignal()方法原型(PyQt官網(wǎng)的定義):
PyQt5.QtCore.pyqtSignal(types[, name[, revision=0[, arguments=[]]]])
Create one or more overloaded unbound signals as a class attribute.Parameters:
types – the types that define the C++ signature of the signal. Each type may be a Python type object or a string that is the name of a C++ type. Alternatively each may be a sequence of type arguments. In this case each sequence defines the signature of a different signal overload. The first overload will be the default.name – the name of the signal. If it is omitted then the name of the class attribute is used. This may only be given as a keyword argument.
revision – the revision of the signal that is exported to QML. This may only be given as a keyword argument.
arguments – the sequence of the names of the signal's arguments that is exported to QML. This may only be given as a keyword argument.
Return type: an unbound signal
新的信號(hào)應(yīng)該定義在QObject的子類中。新的信號(hào)必須作為定義類的一部分,不允許將信號(hào)作為類的屬性在類定義之后通過(guò)動(dòng)態(tài)的方式進(jìn)行添加。通過(guò)這種方式新的信號(hào)才能自動(dòng)的添加到QMetaObject類中。這就意味這新定義的信號(hào)將會(huì)出現(xiàn)在Qt Designer,并且可以通過(guò)QMetaObject API實(shí)現(xiàn)內(nèi)省。
通過(guò)下面的例子,了解一下關(guān)于signal的定義:
from PyQt5.QtCore import QObject, pyqtSignal class NewSignal(QObject): # 定義了一個(gè)“closed”信號(hào),該信號(hào)沒(méi)有參數(shù)據(jù) closed= pyqtSignal() # 定義了一個(gè)"range_changed"信號(hào),該信號(hào)有兩個(gè)int類型的參數(shù) range_changed = pyqtSignal(int, int, name='rangeChanged')
自定義信號(hào)的發(fā)射,通過(guò)emit()方法類實(shí)現(xiàn),具體參見(jiàn)該函數(shù)的原型:
emit(*args)
Parameters: args – the optional sequence of arguments to pass to any connected slots.
通過(guò)下面的例子,了解一下關(guān)于emit()的使用:
from PyQt5.QtCore import QObject, pyqtSignal class NewSignal(QObject): # 一個(gè)valueChanged的信號(hào),該信號(hào)沒(méi)有參數(shù). valueChanged = pyqtSignal() def connect_and_emit_valueChanged(self): # 綁定信號(hào)和槽函數(shù) self.valueChanged.connect(self.handle_valueChanged) # 發(fā)射信號(hào). self.trigger.emit() def handle_valueChanged(self): print("trigger signal received")
示例說(shuō)明:
自定義信號(hào)的一般流程如下:
1、定義信號(hào)
2、定義槽函數(shù)
3、綁定信號(hào)和槽
4、發(fā)射信號(hào)
通過(guò)代碼示例來(lái)了解一下信號(hào)的自定義過(guò)程:
#-*- coding:utf-8 -*- ''' defined Signal ''' __author__ = 'Tony Zhu' import sys from PyQt5.QtCore import pyqtSignal, QObject, Qt, pyqtSlot from PyQt5.QtWidgets import QWidget, QApplication, QGroupBox, QPushButton, QLabel, QCheckBox, QSpinBox, QHBoxLayout, QComboBox, QGridLayout class SignalEmit(QWidget): helpSignal = pyqtSignal(str) printSignal = pyqtSignal(list) #聲明一個(gè)多重載版本的信號(hào),包括了一個(gè)帶int和str類型參數(shù)的信號(hào),以及帶str參數(shù)的信號(hào) previewSignal = pyqtSignal([int,str],[str]) def __init__(self): super().__init__() self.initUI() def initUI(self): self.creatContorls("打印控制:") self.creatResult("操作結(jié)果:") layout = QHBoxLayout() layout.addWidget(self.controlsGroup) layout.addWidget(self.resultGroup) self.setLayout(layout) self.helpSignal.connect(self.showHelpMessage) self.printSignal.connect(self.printPaper) self.previewSignal[str].connect(self.previewPaper) self.previewSignal[int,str].connect(self.previewPaperWithArgs) self.printButton.clicked.connect(self.emitPrintSignal) self.previewButton.clicked.connect(self.emitPreviewSignal) self.setGeometry(300, 300, 290, 150) self.setWindowTitle('defined signal') self.show() def creatContorls(self,title): self.controlsGroup = QGroupBox(title) self.printButton = QPushButton("打印") self.previewButton = QPushButton("預(yù)覽") numberLabel = QLabel("打印份數(shù):") pageLabel = QLabel("紙張類型:") self.previewStatus = QCheckBox("全屏預(yù)覽") self.numberSpinBox = QSpinBox() self.numberSpinBox.setRange(1, 100) self.styleCombo = QComboBox(self) self.styleCombo.addItem("A4") self.styleCombo.addItem("A5") controlsLayout = QGridLayout() controlsLayout.addWidget(numberLabel, 0, 0) controlsLayout.addWidget(self.numberSpinBox, 0, 1) controlsLayout.addWidget(pageLabel, 0, 2) controlsLayout.addWidget(self.styleCombo, 0, 3) controlsLayout.addWidget(self.printButton, 0, 4) controlsLayout.addWidget(self.previewStatus, 3, 0) controlsLayout.addWidget(self.previewButton, 3, 1) self.controlsGroup.setLayout(controlsLayout) def creatResult(self,title): self.resultGroup = QGroupBox(title) self.resultLabel = QLabel("") layout = QHBoxLayout() layout.addWidget(self.resultLabel) self.resultGroup.setLayout(layout) def emitPreviewSignal(self): if self.previewStatus.isChecked() == True: self.previewSignal[int,str].emit(1080," Full Screen") elif self.previewStatus.isChecked() == False: self.previewSignal[str].emit("Preview") def emitPrintSignal(self): pList = [] pList.append(self.numberSpinBox.value ()) pList.append(self.styleCombo.currentText()) self.printSignal.emit(pList) def printPaper(self,list): self.resultLabel.setText("Print: "+"份數(shù):"+ str(list[0]) +" 紙張:"+str(list[1])) def previewPaperWithArgs(self,style,text): self.resultLabel.setText(str(style)+text) def previewPaper(self,text): self.resultLabel.setText(text) def keyPressEvent(self, event): if event.key() == Qt.Key_F1: self.helpSignal.emit("help message") def showHelpMessage(self,message): self.resultLabel.setText(message) #self.statusBar().showMessage(message) if __name__ == '__main__': app = QApplication(sys.argv) dispatch = SignalEmit() sys.exit(app.exec_())
運(yùn)行該函數(shù)之后的效果如下:
示例說(shuō)明:
通過(guò)一個(gè)模擬打印的界面來(lái)詳細(xì)說(shuō)明一下關(guān)于信號(hào)的自定義,在打印的時(shí)候可以設(shè)定打印的分?jǐn)?shù),紙張類型,觸發(fā)“打印”按鈕之后,將執(zhí)行結(jié)果顯示到右側(cè);通過(guò)全屏預(yù)覽QCheckBox來(lái)選擇是否通過(guò)全屏模式進(jìn)行預(yù)覽,將執(zhí)行結(jié)果顯示到右側(cè)。
通過(guò)點(diǎn)擊F1快捷鍵,可以顯示helpMessage信息。
代碼分析:
L12~15:
helpSignal = pyqtSignal(str) printSignal = pyqtSignal(list) #聲明一個(gè)多重載版本的信號(hào),包括了一個(gè)帶int和str類型參數(shù)的信號(hào),以及帶str參數(shù)的信號(hào) previewSignal = pyqtSignal([int,str],[str])
通過(guò)pyqtSignal()定義了三個(gè)信號(hào),helpSignal ,printSignal ,previewSignal 。其中:
helpSignal 為str參數(shù)類型的信號(hào);
printSignal 為list參數(shù)類型的信號(hào);
previewSignal為一個(gè)多重載版本的信號(hào),包括了一個(gè)帶int和str類型參數(shù)的信號(hào),以及str類行的參數(shù)。
self.helpSignal.connect(self.showHelpMessage) self.printSignal.connect(self.printPaper) self.previewSignal[str].connect(self.previewPaper) self.previewSignal[int,str].connect(self.previewPaperWithArgs) self.printButton.clicked.connect(self.emitPrintSignal) self.previewButton.clicked.connect(self.emitPreviewSignal)
綁定信號(hào)和槽;著重說(shuō)明一下多重載版本的信號(hào)的綁定,previewSignal有兩個(gè)版本previewSignal(str),previewSignal(int,str)。由于存在兩個(gè)版本,從因此在綁定的時(shí)候需要顯式的指定信號(hào)和槽的綁定關(guān)系。
具體如下:
self.previewSignal[str].connect(self.previewPaper) self.previewSignal[int,str].connect(self.previewPaperWithArgs)
其中[str]參數(shù)的previewSignal信號(hào)綁定previewPaper();[int,str]的previewSignal信號(hào)綁定previewPaperWithArgs()
L72~76:
def emitPreviewSignal(self): if self.previewStatus.isChecked() == True: self.previewSignal[int,str].emit(1080," Full Screen") elif self.previewStatus.isChecked() == False: self.previewSignal[str].emit("Preview")
多重載版本的信號(hào)的發(fā)射也需要制定對(duì)應(yīng)發(fā)射的版本,類似同信號(hào)的版定。
L78~82:
def emitPrintSignal(self): pList = [] pList.append(self.numberSpinBox.value ()) pList.append(self.styleCombo.currentText()) self.printSignal.emit(pList)
如代碼中所示,在信號(hào)發(fā)射的時(shí)候可以傳遞python數(shù)據(jù)類型的參數(shù),在本例中傳遞list類型的參數(shù)pList.
L93~96:
def keyPressEvent(self, event): if event.key() == Qt.Key_F1: self.helpSignal.emit("help message")
通過(guò)復(fù)寫keyPressEvent()方法,將F1快捷鍵進(jìn)行功能的拓展。在windows的大部分應(yīng)用,我們都會(huì)使用一些快捷鍵來(lái)快速的完成某些特定的功能。比如F1鍵,會(huì)快速調(diào)出幫助界面。那我們就可以復(fù)寫keyPressEvent()方法來(lái)模擬發(fā)送所需的信號(hào),來(lái)完成我們的對(duì)應(yīng)任務(wù).
注意事項(xiàng):
1、自定義的信號(hào)在init()函數(shù)之前定義;
2、自定義型號(hào)可以傳遞,str、int、list、object、float、tuple、dict等很多類型的參數(shù);
3、注意signal和slot的調(diào)用邏輯,避免signal和slot之間出現(xiàn)死循環(huán)。如在slot方法中繼續(xù)發(fā)射該信號(hào);
總結(jié)
以上就是本文關(guān)于pyqt5自定義信號(hào)實(shí)例解析的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
Python?Pandas:DataFrame一列切分成多列、分隔符切分選字段方式
這篇文章主要介紹了Python?Pandas:DataFrame一列切分成多列、分隔符切分選字段方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09Pytorch從0實(shí)現(xiàn)Transformer的實(shí)踐
本文主要介紹了Pytorch從0實(shí)現(xiàn)Transformer的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05python中enumerate函數(shù)遍歷元素用法分析
這篇文章主要介紹了python中enumerate函數(shù)遍歷元素用法,結(jié)合實(shí)例形式分析了enumerate函數(shù)遍歷元素的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-03-03