Python PyQt5學習之自定義信號
PyQ5已經自動定義了很多QT自建的信號。但是在實際的使用中為了靈活使用信號與槽機制,可以根據需要自定義信號。通過使用pyqtSignal()方法定義新的信號,新的信號作為類的屬性。
自定義signal說明:
新的信號應該定義在QObject的子類中。新的信號必須作為定義類的一部分,不允許將信號作為類的屬性在類定義之后通過動態(tài)的方式進行添加。通過這種方式新的信號才能自動的添加到QMetaObject類中。這就意味這新定義的信號將會出現在Qt Designer,并且可以通過QMetaObject API實現內省。
自定義信號的發(fā)射,通過emit()方法類實現
自定義信號的一般流程如下:
- 定義信號
- 定義槽函數
- 綁定信號和槽
- 發(fā)射信號
代碼示例
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)
#聲明一個多重載版本的信號,包括了一個帶int和str類型參數的信號,以及帶str參數的信號
previewSignal = pyqtSignal([int,str],[str])
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.creatContorls("打印控制:")
self.creatResult("操作結果:")
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("預覽")
numberLabel = QLabel("打印份數:")
pageLabel = QLabel("紙張類型:")
self.previewStatus = QCheckBox("全屏預覽")
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: "+"份數:"+ 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_())
樣例說明:
通過一個模擬打印的界面來詳細說明一下關于信號的自定義,在打印的時候可以設定打印的分數,紙張類型,觸發(fā)“打印”按鈕之后,將執(zhí)行結果顯示到右側;通過全屏預覽QCheckBox來選擇是否通過全屏模式進行預覽,將執(zhí)行結果顯示到右側。
通過點擊F1快捷鍵,可以顯示helpMessage信息。
界面分析:
該界面主要由兩個部分組成:一個是打印控制,另一個是操作結果。
通過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("預覽")
numberLabel = QLabel("打印份數:")
pageLabel = QLabel("紙張類型:")
self.previewStatus = QCheckBox("全屏預覽")
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是一個計數器控件,允許用戶選擇一個整數值通過單擊向上向下或者按鍵盤上的上下鍵來增加減少當前顯示的值,當然用戶也可以輸入值。
QComboBox是一個集按鈕和下拉選項于一體的控件,也稱做下拉列表框。
然后通過creatResult定義“操作結果”界面:
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) #聲明一個多重載版本的信號,包括了一個帶int和str類型參數的信號,以及帶str參數的信號 previewSignal = pyqtSignal([int,str],[str])
通過pyqtSignal()定義了三個信號,helpSignal,printSignal,previewSignal。其中:
- helpSignal 為str參數類型的信號。
- printSignal 為list參數類型的信號。
- previewSignal為一個多重載版本的信號,包括了一個帶int和str類型參數的信號,以及str類行的參數。
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)
綁定信號和槽。
著重說明一下多重載版本的信號的綁定,previewSignal有兩個版本previewSignal(str),previewSignal(int,str)。由于存在兩個版本,從因此在綁定的時候需要顯式的指定信號和槽的綁定關系。
具體如下:
self.previewSignal[str].connect(self.previewPaper) self.previewSignal[int,str].connect(self.previewPaperWithArgs)
其中[str]參數的previewSignal信號綁定previewPaper();[int,str]的previewSignal信號綁定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")
多重載版本的信號的發(fā)射也需要制定對應發(fā)射的版本,類似同信號的版定。
def emitPrintSignal(self):
pList = []
pList.append(self.numberSpinBox.value ())
pList.append(self.styleCombo.currentText())
self.printSignal.emit(pList)
如代碼中所示,在信號發(fā)射的時候可以傳遞python數據類型的參數,在本例中傳遞list類型的參數pList。
def keyPressEvent(self, event):
if event.key() == Qt.Key_F1:
self.helpSignal.emit("help message")
通過復寫keyPressEvent()方法,將F1快捷鍵進行功能的拓展。在windows的大部分應用,我們都會使用一些快捷鍵來快速的完成某些特定的功能。比如F1鍵,會快速調出幫助界面,那就可以復寫keyPressEvent()方法來模擬發(fā)送所需的信號,來完成對應任務。

注意事項:
1.自定義的信號在init()函數之前定義
2.自定義型號可以傳遞,str、int、list、object、float、tuple、dict等很多類型的參數
3.注意signal和slot的調用邏輯,避免signal和slot之間出現死循環(huán)。如在slot方法中繼續(xù)發(fā)射該信號
到此這篇關于Python PyQt5學習之自定義信號的文章就介紹到這了,更多相關Python PyQt5信號內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python?Diagrams創(chuàng)建高質量圖表和流程圖實例探究
Python?Diagrams是一個強大的Python庫,使創(chuàng)建這些圖表變得簡單且靈活,本文將深入介紹Python?Diagrams,包括其基本概念、安裝方法、示例代碼以及一些高級用法,以幫助大家充分利用這一工具來創(chuàng)建令人印象深刻的圖表2024-01-01

