SoFunction
Updated on 2024-11-16

Example analysis of pyqt5 custom signal

This article studies the main pyqt5 custom signal example analysis of the contents of the following.

PyQt5 has automatically defined a lot of QT built-in signals. However, in practice, in order to use signals and slots flexibly, we can customize signals as needed. pyqtSignal() method can be used to define new signals, and new signals are used as attributes of the class.

Customize the signal description:

The pyqtSignal() method prototype (as defined on the official PyQt website):

(types[, name[, revision=0[, arguments=[]]]])
Create one or more overloaded unbound signals as a class attribute.

Parameters:
types – the types that define the C++ signature of the signal. Each type may be a Python type object or a string that is the name of a C++ type. Alternatively each may be a sequence of type arguments. In this case each sequence defines the signature of a different signal overload. The first overload will be the default.

name – the name of the signal. If it is omitted then the name of the class attribute is used. This may only be given as a keyword argument.

revision – the revision of the signal that is exported to QML. This may only be given as a keyword argument.

arguments – the sequence of the names of the signal's arguments that is exported to QML. This may only be given as a keyword argument.
Return type: an unbound signal

The new signal should be defined in a subclass of QObject. New signals must be part of the defining class, it is not allowed to add signals dynamically as attributes of the class after the class has been defined. In this way new signals are automatically added to the QMetaObject class. This means that newly defined signals will appear in the Qt Designer and can be introspected through the QMetaObject API.

Learn about the definition of signal with the examples below:

from  import QObject, pyqtSignal

class NewSignal(QObject):

  # Defines a "closed" signal, which has no parameters according to the
  closed= pyqtSignal()

  # Defines a "range_changed" signal with two parameters of type int.
  range_changed = pyqtSignal(int, int, name='rangeChanged')

Custom signals are emitted through the emit() method class, see the prototype of this function for details:

emit(*args)
Parameters: args – the optional sequence of arguments to pass to any connected slots.

Learn about the use of emit() with the following example:

from  import QObject, pyqtSignal

class NewSignal(QObject):

  # A valueChanged signal with no arguments.
  valueChanged = pyqtSignal()

  def connect_and_emit_valueChanged(self):
    # Bind signals and slot functions
    (self.handle_valueChanged)

    # Transmit signals.
    ()

  def handle_valueChanged(self):
    print("trigger signal received")

Example Description:

The general process for customizing signals is as follows:

1. Define the signal
2、Define the slot function
3. Binding signals and slots
4. Transmit signals

Take a look at the signal customization process with a code example:

#-*- coding:utf-8 -*-
'''
defined Signal
'''
__author__ = 'Tony Zhu'
import sys
from  import pyqtSignal, QObject, Qt, pyqtSlot
from  import QWidget, QApplication, QGroupBox, QPushButton, QLabel, QCheckBox, QSpinBox, QHBoxLayout, QComboBox, QGridLayout


class SignalEmit(QWidget):
  helpSignal = pyqtSignal(str)
  printSignal = pyqtSignal(list)
  # Declare a multi-overloaded version of the signal, including a signal with int and str type parameters, and a signal with str parameter
  previewSignal = pyqtSignal([int,str],[str])
  def __init__(self):
    super().__init__()    
    ()


  def initUI(self):      

    ("Print Control:")
    ("Results of the operation:")

    layout = QHBoxLayout()
    ()
    ()
    (layout)

    ()
    ()
    [str].connect()
    [int,str].connect() 
    ()
    ()

    (300, 300, 290, 150)
    ('defined signal')
    ()

  def creatContorls(self,title):
     = QGroupBox(title)
     = QPushButton("Print.")
     = QPushButton("Preview.")
    numberLabel = QLabel("Number of copies printed:")
    pageLabel = QLabel("Paper type:")
     = QCheckBox("Full-screen preview.")
     = QSpinBox()
    (1, 100)
     = QComboBox(self)
    ("A4")
    ("A5")

    controlsLayout = QGridLayout()
    (numberLabel, 0, 0)
    (, 0, 1)
    (pageLabel, 0, 2)
    (, 0, 3)
    (, 0, 4)
    (, 3, 0)
    (, 3, 1)
    (controlsLayout)

  def creatResult(self,title):
     = QGroupBox(title)
     = QLabel("")
    layout = QHBoxLayout()
    ()
    (layout)

  def emitPreviewSignal(self):
    if () == True:
      [int,str].emit(1080," Full Screen")
    elif () == False:
      [str].emit("Preview")

  def emitPrintSignal(self):
    pList = []
    ( ())
    (())
    (pList)

  def printPaper(self,list):
    ("Print: "+"Number of copies:"+ str(list[0]) +" Paper:"+str(list[1]))

  def previewPaperWithArgs(self,style,text):
    (str(style)+text)

  def previewPaper(self,text):
    (text)     

  def keyPressEvent(self, event):

    if () == Qt.Key_F1:
      ("help message")

  def showHelpMessage(self,message):
    (message)
    #().showMessage(message)


if __name__ == '__main__':

  app = QApplication()
  dispatch = SignalEmit()
  (app.exec_())

The effect after running the function is as follows:

Example Description:

Through a simulation of the print interface to explain in detail about the customization of the signal, you can set the print score, paper type, trigger the "Print" button, the results will be displayed to the right; through the full-screen preview QCheckBox to choose whether to preview through the full-screen mode, the results will be displayed to the right side of the implementation. QCheckBox can be used to select whether to preview the result in full screen mode or not, and the result will be displayed on the right side.
The helpMessage message can be displayed by clicking the F1 shortcut.

Code Analysis:

L12~15:

  helpSignal = pyqtSignal(str)
  printSignal = pyqtSignal(list)
  # Declare a multi-overloaded version of the signal, including a signal with int and str type parameters, and a signal with str parameter
  previewSignal = pyqtSignal([int,str],[str])

Three signals are defined through pyqtSignal(), helpSignal , printSignal , and previewSignal . Among them:

helpSignal A signal of type str argument;

printSignal A signal of type list argument;

previewSignal is a multi-overloaded version of the signal that includes a signal with parameters of type int and str, as well as parameters of the str class line.

()
()
[str].connect()    
[int,str].connect()    
 ()    
()

Binding signals and slots; highlighting the binding of multiple overloaded versions of signals, there are two versions of previewSignal previewSignal(str), previewSignal(int,str). Since there are two versions, from therefore you need to explicitly specify the signal and slot bindings when binding.

The details are as follows:

[str].connect() [int,str].connect()

where the previewSignal signal for the [str] argument binds previewPaper(); the previewSignal signal for the [int,str] binds previewPaperWithArgs()

L72~76:

  def emitPreviewSignal(self):
    if () == True:
      [int,str].emit(1080," Full Screen")
    elif () == False:
      [str].emit("Preview")

The emission of multiple heavy-duty versions of a signal also requires the development of a version of the corresponding emission, similar to the versioning of the same signal.

L78~82:

  def emitPrintSignal(self):
    pList = []
    ( ())
    (())
    (pList)

As shown in the code, you can pass parameters of python data types when signaling, in this case the list type parameter pList.

L93~96:

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

Extend the functionality of F1 shortcut keys by rewriting the keyPressEvent() method. In most of the windows applications, we use some shortcut keys to quickly accomplish some specific functions. For example, the F1 key will quickly bring up the help screen. Then we can rewrite the keyPressEvent() method to simulate sending the required signal to complete our corresponding task.

Caveats:

1. Customized signals are defined before the init() function;
2, custom models can be passed , str, int, list, object, float, tuple, dict and many other types of parameters;
3. Pay attention to the call logic of signal and slot to avoid a dead loop between signal and slot. Such as in the slot method to continue to emit the signal;

summarize

Above is the entire content of this article on pyqt5 custom signal example analysis, I hope you can help. Interested friends can continue to refer to other related topics on this site, if there are inadequacies, welcome to leave a message to point out. Thank you for the support of friends on this site!