Introduction to Python Qt GUI design signal and slot function

preface

In the previous chapter, we have explained how to use the py file template generated by Qt, but this can only realize the graphical interface. It is not involved in the logical processing and function response of the whole GUI. Here is the same as the callback and other response functions of each control in MATLAB. The function response of Qt is divided into signal and slot function. The signal is the user's action, and the slot function is the corresponding response.

1, Built in signal and slot function

1. New project

First, let's create a project. Unlike before, here we need to create the corresponding c + + file. We don't need to edit it, just to view some information.

All the way.


Open the new ui file:

Design the interface:

2. Correlation between signal and slot function


Press and hold the left button to confirm, and drag the pushbutton to the outside of the interface:


Click OK to close the dialog window. Next, use pyuic5 -o Proj2_dialog.py dialog.ui generates a py file. The file name needs to be changed to its own. Open the PY file:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'dialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(342, 240)
        self.plainTextEdit = QtWidgets.QPlainTextEdit(Dialog)
        self.plainTextEdit.setGeometry(QtCore.QRect(9, 59, 281, 138))
        font = QtGui.QFont()
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.plainTextEdit.setFont(font)
        self.plainTextEdit.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
        self.plainTextEdit.setCenterOnScroll(False)
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.horizontalLayoutWidget = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(80, 30, 240, 21))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.radioButton_3 = QtWidgets.QRadioButton(self.horizontalLayoutWidget)
        self.radioButton_3.setObjectName("radioButton_3")
        self.horizontalLayout.addWidget(self.radioButton_3)
        self.radioButton_2 = QtWidgets.QRadioButton(self.horizontalLayoutWidget)
        self.radioButton_2.setObjectName("radioButton_2")
        self.horizontalLayout.addWidget(self.radioButton_2)
        self.radioButton = QtWidgets.QRadioButton(self.horizontalLayoutWidget)
        self.radioButton.setObjectName("radioButton")
        self.horizontalLayout.addWidget(self.radioButton)
        self.horizontalLayoutWidget_3 = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget_3.setGeometry(QtCore.QRect(9, 203, 311, 30))
        self.horizontalLayoutWidget_3.setObjectName("horizontalLayoutWidget_3")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_3)
        self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_3.setSpacing(30)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.pushButton_3 = QtWidgets.QPushButton(self.horizontalLayoutWidget_3)
        self.pushButton_3.setObjectName("pushButton_3")
        self.horizontalLayout_3.addWidget(self.pushButton_3)
        self.pushButton_2 = QtWidgets.QPushButton(self.horizontalLayoutWidget_3)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout_3.addWidget(self.pushButton_2)
        self.pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget_3)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout_3.addWidget(self.pushButton)
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(20, 10, 54, 20))
        self.label.setObjectName("label")
        self.horizontalLayoutWidget_2 = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(80, 10, 240, 21))
        self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.checkBox_3 = QtWidgets.QCheckBox(self.horizontalLayoutWidget_2)
        self.checkBox_3.setObjectName("checkBox_3")
        self.horizontalLayout_2.addWidget(self.checkBox_3)
        self.checkBox_2 = QtWidgets.QCheckBox(self.horizontalLayoutWidget_2)
        self.checkBox_2.setObjectName("checkBox_2")
        self.horizontalLayout_2.addWidget(self.checkBox_2)
        self.checkBox = QtWidgets.QCheckBox(self.horizontalLayoutWidget_2)
        self.checkBox.setObjectName("checkBox")
        self.horizontalLayout_2.addWidget(self.checkBox)
        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(20, 30, 54, 16))
        self.label_2.setObjectName("label_2")
# The correlation of slot function is here
        self.retranslateUi(Dialog)
        self.pushButton_2.clicked.connect(Dialog.accept) # Here is confirmation
        self.pushButton.clicked.connect(Dialog.close)   # This is cancel
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.plainTextEdit.setPlainText(_translate("Dialog", "Hello World!"))
        self.radioButton_3.setText(_translate("Dialog", "Black    "))
        self.radioButton_2.setText(_translate("Dialog", "Red   "))
        self.radioButton.setText(_translate("Dialog", "Blue"))
        self.pushButton_3.setText(_translate("Dialog", "empty"))
        self.pushButton_2.setText(_translate("Dialog", "confirm"))
        self.pushButton.setText(_translate("Dialog", "cancel"))
        self.label.setText(_translate("Dialog", "Font style"))
        self.checkBox_3.setText(_translate("Dialog", "Underline"))
        self.checkBox_2.setText(_translate("Dialog", "Italic"))
        self.checkBox.setText(_translate("Dialog", "Bold"))
        self.label_2.setText(_translate("Dialog", "Font color"))


According to the previous single inheritance method, we write another file to test:

import  sys
from PyQt5.QtWidgets import QApplication, QDialog
from Proj2_dialog import Ui_Dialog

class QmyDialog(QDialog):
    def __init__(self):
        super(QmyDialog, self).__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
 #   def on_pushButton_3_clicked(self): these two sentences are unnecessary
  #      self.ui.plainTextEdit.clear()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    MyDialog = QmyDialog()
    MyDialog.show()
    sys.exit(app.exec_())


Click OK and cancel to close the window.

2, Custom slot function

Suppose we want to clear all the text in the text editor when we click the empty button, so we need to define the relevant slot function of dialog.

Right click the empty button and select go to slot function:

This is the signal it has as a pushbutton. Click OK and it will automatically jump to a c + + file. This is the name of the associated slot function. We copy it into our own defined class as a class method:

import  sys
from PyQt5.QtWidgets import QApplication, QDialog
from Proj2_dialog import Ui_Dialog

class QmyDialog(QDialog):
    def __init__(self):
        super(QmyDialog, self).__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
    def on_pushButton_3_clicked(self): # This is the self-defined slot function
       self.ui.plainTextEdit.clear()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    MyDialog = QmyDialog()
    MyDialog.show()
    sys.exit(app.exec_())

Run, click the empty button and you will find that the text has been cleared, perfect!

summary

The c + + file we generated here is actually useless. It's just to check the name of the generated slot function. In fact, we also omit the manual correlation part. For example, compared with the built-in slot function, our customized slot function lacks the following statement:

        self.pushButton_2.clicked.connect(Dialog.accept) # Here is confirmation
        self.pushButton.clicked.connect(Dialog.close)   # This is cancel

This is because Qt helps us associate automatically, as long as the slot function we name meets a certain specification, such as: on_pushButton_3_clicked(self): the naming rules conform to on_< Object name > < signal name > () is enough. We notice that the py file automatically generated above also contains the following sentence:

        self.pushButton_2.clicked.connect(Dialog.accept) # Here is confirmation
        self.pushButton.clicked.connect(Dialog.close)   # This is cancel
        QtCore.QMetaObject.connectSlotsByName(Dialog)  # Here is automatic association

If we don't have the following code, we also need to manually associate as above:

self.pushButton_3.clicked.connect(Dialog.on_pushButton_3_clicked)

Keywords: Python GUI pyqt

Added by bionicdonkey on Sat, 29 Jan 2022 10:48:30 +0200