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è)模擬打印的界面來(lái)詳細(xì)說明一下關(guān)于信號(hào)的自定義,在打印的時(shí)候可以設(shè)定打印的分?jǐn)?shù),紙張類型,觸發(fā)“打印”按鈕之后,將執(zhí)行結(jié)果顯示到右側(cè);通過全屏預(yù)覽QCheckBox來(lái)選擇是否通過全屏模式進(jìn)行預(yù)覽,將執(zhí)行結(jié)果顯示到右側(cè)。
通過點(diǎn)擊F1快捷鍵,可以顯示helpMessage信息。
界面分析:
該界面主要由兩個(gè)部分組成:一個(gè)是打印控制,另一個(gè)是操作結(jié)果。
通過QHBoxLayout組合起來(lái),如下所示:
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ù)值通過單擊向上向下或者按鍵盤上的上下鍵來(lái)增加減少當(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ì)使用一些快捷鍵來(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)
到此這篇關(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庫(kù)圖形界面開發(fā)之PyQt5信號(hào)與槽的高級(jí)使用技巧裝飾器信號(hào)與槽詳細(xì)使用方法與實(shí)例
- python GUI庫(kù)圖形界面開發(fā)之PyQt5信號(hào)與槽的高級(jí)使用技巧(自定義信號(hào)與槽)詳解與實(shí)例
- python GUI庫(kù)圖形界面開發(fā)之PyQt5信號(hào)與槽基礎(chǔ)使用方法與實(shí)例
- python GUI庫(kù)圖形界面開發(fā)之PyQt5信號(hào)與槽基本操作
- python GUI庫(kù)圖形界面開發(fā)之PyQt5信號(hào)與槽機(jī)制、自定義信號(hào)基礎(chǔ)介紹
相關(guān)文章
Python實(shí)現(xiàn)合并兩個(gè)字典的8種方法
Python有多種方法可以通過使用各種函數(shù)和構(gòu)造函數(shù)來(lái)合并字典,本文主要介紹了Python實(shí)現(xiàn)合并兩個(gè)字典的8種方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07
自己編程中遇到的Python錯(cuò)誤和解決方法匯總整理
這篇文章主要介紹了自己編程中遇到的Python錯(cuò)誤和解決方法匯總整理,本文收集整理了較多的案例,需要的朋友可以參考下2015-06-06
Python實(shí)現(xiàn)指定數(shù)組下標(biāo)值正序與倒序排序算法功能舉例
在程序中,經(jīng)常需要按數(shù)組倒序或反序重新排列數(shù)組,下面這篇文章主要給大家介紹了關(guān)于Python實(shí)現(xiàn)指定數(shù)組下標(biāo)值正序與倒序排序算法功能的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
數(shù)據(jù)庫(kù)連接池DBUtils的安裝使用方法
DBUtils是Python的一個(gè)用于實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接池的模塊,這篇文章主要介紹了數(shù)據(jù)庫(kù)連接池DBUtils的安裝使用方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-03-03
Python實(shí)現(xiàn)合并帶有嵌入圖片的單元格
這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)合并帶有嵌入圖片的單元格,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-12-12
Python?Diagrams創(chuàng)建高質(zhì)量圖表和流程圖實(shí)例探究
Python?Diagrams是一個(gè)強(qiáng)大的Python庫(kù),使創(chuàng)建這些圖表變得簡(jiǎn)單且靈活,本文將深入介紹Python?Diagrams,包括其基本概念、安裝方法、示例代碼以及一些高級(jí)用法,以幫助大家充分利用這一工具來(lái)創(chuàng)建令人印象深刻的圖表2024-01-01
詳解Python OpenCV圖像分割算法的實(shí)現(xiàn)
圖像分割是指根據(jù)灰度、色彩、空間紋理、幾何形狀等特征把圖像劃分成若干個(gè)互不相交的區(qū)域。本文就來(lái)和大家聊聊OpenCV的圖像分割算法及基于輪廓的字符分離,感興趣的可以了解一下2022-08-08
Pycharm 解決自動(dòng)格式化沖突的設(shè)置操作
這篇文章主要介紹了Pycharm 解決自動(dòng)格式化沖突的設(shè)置操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2021-01-01

