網站首頁 編程語言 正文
PyQ5已經自動定義了很多QT自建的信號。但是在實際的使用中為了靈活使用信號與槽機制,可以根據需要自定義信號。通過使用pyqtSignal()方法定義新的信號,新的信號作為類的屬性。
自定義signal說明:
新的信號應該定義在QObject的子類中。新的信號必須作為定義類的一部分,不允許將信號作為類的屬性在類定義之后通過動態的方式進行添加。通過這種方式新的信號才能自動的添加到QMetaObject類中。這就意味這新定義的信號將會出現在Qt Designer,并且可以通過QMetaObject API實現內省。
自定義信號的發射,通過emit()方法類實現
自定義信號的一般流程如下:
- 定義信號
- 定義槽函數
- 綁定信號和槽
- 發射信號
代碼示例
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_())
樣例說明:
通過一個模擬打印的界面來詳細說明一下關于信號的自定義,在打印的時候可以設定打印的分數,紙張類型,觸發“打印”按鈕之后,將執行結果顯示到右側;通過全屏預覽QCheckBox來選擇是否通過全屏模式進行預覽,將執行結果顯示到右側。
通過點擊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")
多重載版本的信號的發射也需要制定對應發射的版本,類似同信號的版定。
def emitPrintSignal(self): pList = [] pList.append(self.numberSpinBox.value ()) pList.append(self.styleCombo.currentText()) self.printSignal.emit(pList)
如代碼中所示,在信號發射的時候可以傳遞python數據類型的參數,在本例中傳遞list類型的參數pList。
def keyPressEvent(self, event): if event.key() == Qt.Key_F1: self.helpSignal.emit("help message")
通過復寫keyPressEvent()方法,將F1快捷鍵進行功能的拓展。在windows的大部分應用,我們都會使用一些快捷鍵來快速的完成某些特定的功能。比如F1鍵,會快速調出幫助界面,那就可以復寫keyPressEvent()方法來模擬發送所需的信號,來完成對應任務。
注意事項:
1.自定義的信號在init()函數之前定義
2.自定義型號可以傳遞,str、int、list、object、float、tuple、dict等很多類型的參數
3.注意signal和slot的調用邏輯,避免signal和slot之間出現死循環。如在slot方法中繼續發射該信號
原文鏈接:https://blog.csdn.net/kobepaul123/article/details/122972224
相關推薦
- 2023-03-04 Google大佬都用的廣播goAsync源碼分析_Android
- 2022-12-21 Python中的取整、取余運算方法_python
- 2022-11-21 詳解React獲取DOM和獲取組件實例的方式_React
- 2022-08-21 利用Python創建第一個Django框架程序_python
- 2022-12-29 React點擊事件的兩種寫法小結_React
- 2023-02-28 ts定義之 內置對象( BOM,DOM,Date,Promise等 )
- 2022-02-13 如何將pytorch模型部署到安卓
- 2023-02-25 C++11如何引入的尾置返回類型_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支