Python PyQt5學(xué)習(xí)之自定義信號(hào)
PyQ5已經(jīng)自動(dòng)定義了很多QT自建的信號(hào)。但是在實(shí)際的使用中為了靈活使用信號(hào)與槽機(jī)制,可以根據(jù)需要自定義信號(hào)。通過使用pyqtSignal()方法定義新的信號(hào),新的信號(hào)作為類的屬性。
自定義signal說明:
新的信號(hào)應(yīng)該定義在QObject的子類中。新的信號(hào)必須作為定義類的一部分,不允許將信號(hào)作為類的屬性在類定義之后通過動(dòng)態(tài)的方式進(jìn)行添加。通過這種方式新的信號(hào)才能自動(dòng)的添加到QMetaObject類中。這就意味這新定義的信號(hào)將會(huì)出現(xiàn)在Qt Designer,并且可以通過QMetaObject API實(shí)現(xiàn)內(nèi)省。
自定義信號(hào)的發(fā)射,通過emit()方法類實(shí)現(xiàn)
自定義信號(hào)的一般流程如下:
- 定義信號(hào)
- 定義槽函數(shù)
- 綁定信號(hào)和槽
- 發(fā)射信號(hào)
代碼示例
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_())
樣例說明:
通過一個(gè)模擬打印的界面來詳細(xì)說明一下關(guān)于信號(hào)的自定義,在打印的時(shí)候可以設(shè)定打印的分?jǐn)?shù),紙張類型,觸發(fā)“打印”按鈕之后,將執(zhí)行結(jié)果顯示到右側(cè);通過全屏預(yù)覽QCheckBox來選擇是否通過全屏模式進(jìn)行預(yù)覽,將執(zhí)行結(jié)果顯示到右側(cè)。
通過點(diǎn)擊F1快捷鍵,可以顯示helpMessage信息。
界面分析:
該界面主要由兩個(gè)部分組成:一個(gè)是打印控制,另一個(gè)是操作結(jié)果。
通過QHBoxLayout組合起來,如下所示:
layout = QHBoxLayout() layout.addWidget(self.controlsGroup) layout.addWidget(self.resultGroup) self.setLayout(layout)
然后通過creatContorls定義“打印控制”界面,
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)
QSpinBox是一個(gè)計(jì)數(shù)器控件,允許用戶選擇一個(gè)整數(shù)值通過單擊向上向下或者按鍵盤上的上下鍵來增加減少當(dāng)前顯示的值,當(dāng)然用戶也可以輸入值。
QComboBox是一個(gè)集按鈕和下拉選項(xiàng)于一體的控件,也稱做下拉列表框。
然后通過creatResult定義“操作結(jié)果”界面:
def creatResult(self,title): self.resultGroup = QGroupBox(title) self.resultLabel = QLabel("") layout = QHBoxLayout() layout.addWidget(self.resultLabel) self.resultGroup.setLayout(layout)
代碼分析:
helpSignal = pyqtSignal(str) printSignal = pyqtSignal(list) #聲明一個(gè)多重載版本的信號(hào),包括了一個(gè)帶int和str類型參數(shù)的信號(hào),以及帶str參數(shù)的信號(hào) previewSignal = pyqtSignal([int,str],[str])
通過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)和槽。
著重說明一下多重載版本的信號(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()
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)的版定。
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。
def keyPressEvent(self, event): if event.key() == Qt.Key_F1: self.helpSignal.emit("help message")
通過復(fù)寫keyPressEvent()方法,將F1快捷鍵進(jìn)行功能的拓展。在windows的大部分應(yīng)用,我們都會(huì)使用一些快捷鍵來快速的完成某些特定的功能。比如F1鍵,會(huì)快速調(diào)出幫助界面,那就可以復(fù)寫keyPressEvent()方法來模擬發(fā)送所需的信號(hào),來完成對(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)
到此這篇關(guān)于Python PyQt5學(xué)習(xí)之自定義信號(hào)的文章就介紹到這了,更多相關(guān)Python PyQt5信號(hào)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python深度學(xué)習(xí)實(shí)戰(zhàn)PyQt5信號(hào)與槽的連接
- python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽的高級(jí)使用技巧裝飾器信號(hào)與槽詳細(xì)使用方法與實(shí)例
- python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽的高級(jí)使用技巧(自定義信號(hào)與槽)詳解與實(shí)例
- python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽基礎(chǔ)使用方法與實(shí)例
- python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽基本操作
- python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽機(jī)制、自定義信號(hào)基礎(chǔ)介紹
相關(guān)文章
解析pandas apply() 函數(shù)用法(推薦)
這篇文章主要介紹了pandas apply() 函數(shù)用法,大家需要掌握函數(shù)作為一個(gè)對(duì)象,能作為參數(shù)傳遞給其它函數(shù),也能作為函數(shù)的返回值,具體內(nèi)容詳情跟隨小編一起看看吧2021-10-10詳解Python中命令行參數(shù)argparse的常用命令
這篇文章主要為大家詳細(xì)介紹了Python中命令行參數(shù)argparse的一些常用命令,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以了解一下2023-01-01使用 Python 快速實(shí)現(xiàn) HTTP 和 FTP 服務(wù)器的方法
這篇文章主要介紹了使用 Python 快速實(shí)現(xiàn) HTTP 和 FTP 服務(wù)器 的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07在python的WEB框架Flask中使用多個(gè)配置文件的解決方法
所謂配置文件管理,就是在不改變?cè)创a的前提下,擁有兩套(甚至多套)配置文件,分別用于開發(fā)環(huán)境和生產(chǎn)環(huán)境,通過命令行選擇配置文件2014-04-04Python基于分析Ajax請(qǐng)求實(shí)現(xiàn)抓取今日頭條街拍圖集功能示例
這篇文章主要介紹了Python基于分析Ajax請(qǐng)求實(shí)現(xiàn)抓取今日頭條街拍圖集功能,涉及Python針對(duì)今日頭條URL請(qǐng)求與json數(shù)據(jù)處理相關(guān)操作技巧,需要的朋友可以參考下2018-07-07numpy創(chuàng)建神經(jīng)網(wǎng)絡(luò)框架
本文介紹了使用numpy從零搭建了一個(gè)類似于pytorch的深度學(xué)習(xí)框架,可以用在很多地方,有需要的朋友可以自行參考一下2021-08-08Python浮點(diǎn)數(shù)取整、格式化和NaN處理的操作方法
這篇文章主要介紹了Python浮點(diǎn)數(shù)取整、格式化和NaN處理的操作方法,本文較詳細(xì)介紹了取整的三種方法,格式化浮點(diǎn)數(shù)輸出的示例代碼詳解,感興趣的朋友跟隨小編一起看看吧2022-05-05Python APScheduler執(zhí)行使用方法詳解
在本篇文章里小編給大家整理的是一篇關(guān)于Python APScheduler執(zhí)行使用方法的相關(guān)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2020-12-12