PyQt5 (six) signal personnalisé

PyQ5 a automatiquement défini de nombreux signaux auto-construits QT. Mais en utilisation réelle, afin d'utiliser le mécanisme de signal et de fente de manière flexible, vous pouvez personnaliser le signal selon vos besoins. En utilisant la méthode pyqtSignal() pour définir un nouveau signal en tant que propriété de la classe.

Description du signal personnalisé :

Les nouveaux signaux doivent être définis dans des sous-classes de QObject. Le nouveau signal doit faire partie de la classe de définition, il n'est pas autorisé d'ajouter dynamiquement le signal en tant que propriété de la classe une fois la classe définie. De cette manière, de nouveaux signaux sont automatiquement ajoutés à la classe QMetaObject. Cela signifie que le signal nouvellement défini apparaîtra dans Qt Designer et pourra être examiné via l'API QMetaObject.

L'émission de signaux personnalisés, implémentée par la classe de méthode Emit()

Le flux général des signaux personnalisés est le suivant :

  1. définir le signal
  2. définir la fonction de slot
  3. Signaux et créneaux de liaison
  4. transmettre un signal

exemple de code

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_())

Exemple de descriptif :

Grâce à une interface d'impression simulée, nous expliquerons en détail la personnalisation du signal. Lors de l'impression, vous pouvez définir le score d'impression et le type de papier. Après avoir déclenché le bouton "Imprimer", le résultat de l'exécution s'affichera à droite. Sélectionnez si pour prévisualiser en mode plein écran et afficher le résultat de l'exécution à droite.
En appuyant sur la touche de raccourci F1, les informations helpMessage peuvent être affichées.

Analyse des interfaces :

L'interface se compose principalement de deux parties : l'une est le contrôle d'impression et l'autre est le résultat de l'opération .

Combiné via QHBoxLayout comme suit :

layout = QHBoxLayout()
layout.addWidget(self.controlsGroup)
layout.addWidget(self.resultGroup)
self.setLayout(layout)

Définissez ensuite l'interface " print control "  via 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 est un contrôle de compteur qui permet à l'utilisateur de sélectionner une valeur entière pour augmenter ou diminuer la valeur actuellement affichée en cliquant vers le haut ou vers le bas ou en appuyant sur les touches haut et bas du clavier. Bien entendu, l'utilisateur peut également saisir une valeur.

QComboBox est un contrôle qui intègre des boutons et des options déroulantes, également connu sous le nom de zone de liste déroulante.

Définissez ensuite l' interface " résultat de l'opération "  via creatResult :

def creatResult(self,title):
        self.resultGroup = QGroupBox(title)
        self.resultLabel = QLabel("")
        layout = QHBoxLayout()
        layout.addWidget(self.resultLabel)
        self.resultGroup.setLayout(layout)

Analyse de code :

helpSignal = pyqtSignal(str)
printSignal = pyqtSignal(list)
#声明一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及带str参数的信号
previewSignal = pyqtSignal([int,str],[str])

Trois signaux sont définis par pyqtSignal(), helpSignal, printSignal, previewSignal. Où :
helpSignal est le signal du type de paramètre str.
printSignal est le signal du type de paramètre de liste.
previewSignal est une version surchargée du signal, comprenant un signal avec des paramètres de type int et str, et des paramètres de type 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)

Lier les signaux et les slots.

Concentrez-vous sur la liaison de la version multi-charge du signal, previewSignal a deux versions previewSignal (str), previewSignal (int, str). Puisqu'il existe deux versions, il est nécessaire de spécifier explicitement la relation de liaison entre les signaux et les créneaux lors de la liaison.

Les détails sont les suivants :
self.previewSignal[str].connect(self.previewPaper) self.previewSignal[int,str].connect(self.previewPaperWithArgs)
Le signal previewSignal du paramètre [str] est lié à previewPaper(); [int, str] Le signal previewSignal est lié à 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")

La transmission de la version à porteuses multiples du signal nécessite également de formuler la version correspondant à l'émission, similaire à la version du même signal.

def emitPrintSignal(self):
        pList = []
        pList.append(self.numberSpinBox.value ())
        pList.append(self.styleCombo.currentText())
        self.printSignal.emit(pList)

Comme indiqué dans le code, un paramètre de type de données python peut être passé lors de l'émission du signal, dans ce cas le paramètre pList de type list est passé.

def keyPressEvent(self, event):
    if event.key() == Qt.Key_F1:
         self.helpSignal.emit("help message")

En remplaçant la méthode keyPressEvent(), la fonction de la touche de raccourci F1 est étendue. Dans la plupart des applications de Windows, nous utiliserons certaines touches de raccourci pour remplir rapidement certaines fonctions spécifiques. Par exemple, la touche F1 appellera rapidement l'interface d'aide, puis vous pourrez remplacer la méthode keyPressEvent() pour simuler l'envoi du signal requis pour terminer la tâche correspondante.

Précautions:

  1. Les signaux personnalisés sont définis avant la fonction init()
  2. Les modèles personnalisés peuvent être passés, str, int, list, object, float, tuple, dict et de nombreux autres types de paramètres
  3. Faites attention à la logique d'appel du signal et du slot pour éviter une boucle infinie entre le signal et le slot. Comme dans la méthode des slots, continuez à émettre le signal

Cet article est la sixième partie de "Apprendre PyQt5 à partir de zéro" , j'espère que vous pourrez soutenir et apprendre ensemble !


faire référence à:

Série Pyqt5 (huit) - signal personnalisé - Le vent chassant le soleil - Blog CSDN - signal personnalisé pyqt5

Je suppose que tu aimes

Origine blog.csdn.net/kobepaul123/article/details/122972224
conseillé
Classement