日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Python?PyQt5學習之自定義信號_python

作者:Yunlord ? 更新時間: 2022-05-03 編程語言

PyQ5已經自動定義了很多QT自建的信號。但是在實際的使用中為了靈活使用信號與槽機制,可以根據需要自定義信號。通過使用pyqtSignal()方法定義新的信號,新的信號作為類的屬性。

自定義signal說明:

新的信號應該定義在QObject的子類中。新的信號必須作為定義類的一部分,不允許將信號作為類的屬性在類定義之后通過動態的方式進行添加。通過這種方式新的信號才能自動的添加到QMetaObject類中。這就意味這新定義的信號將會出現在Qt Designer,并且可以通過QMetaObject API實現內省。

自定義信號的發射,通過emit()方法類實現

自定義信號的一般流程如下:

  1. 定義信號
  2. 定義槽函數
  3. 綁定信號和槽
  4. 發射信號

代碼示例

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

欄目分類
最近更新