Python Qt GUI设计入门(三)信号与槽函数


前言

在上一章我们已经讲解了如何使用Qt生成的py文件模板,但是这还仅仅只能实现图形界面部分,对于整个GUI的逻辑处理和函数响应都没有涉及,这里就和MATLAB中每个控件的callback和其他响应函数一样。Qt的函数响应分为信号和槽函数,信号就是用户的动作,槽函数就是相应的响应。


一、内置信号和槽函数

1.新建项目

我们首先来创建一个项目,与之前不一样,这里我们需要还要创建相应的c++文件,并不需要我们编辑,只是用于查看一些信息。
在这里插入图片描述
一路选下去。
在这里插入图片描述
在这里插入图片描述
打开新建的ui文件:
在这里插入图片描述
设计好界面:
在这里插入图片描述

2.信号与槽函数的关联

在这里插入图片描述
左键长按 确认pushbutton拖动到界面外:
在这里插入图片描述
在这里插入图片描述
这里是使点击确认按键关闭dialog窗口,下面还是使用pyuic5 -o Proj2_dialog.py dialog.ui 生成py文件,文件名需要改成自己的,打开py文件:

# -*- 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")
# 槽函数的关联在此处
        self.retranslateUi(Dialog)
        self.pushButton_2.clicked.connect(Dialog.accept) # 这里是确认
        self.pushButton.clicked.connect(Dialog.close)   # 这里是取消
        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", "清空"))
        self.pushButton_2.setText(_translate("Dialog", "确认"))
        self.pushButton.setText(_translate("Dialog", "取消"))
        self.label.setText(_translate("Dialog", "字体样式"))
        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", "字体颜色"))


按照之前的单继承方法,我们另写一个文件来测试:

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): 这两句不用
  #      self.ui.plainTextEdit.clear()

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

在这里插入图片描述
这时单击确认和取消按键就可以关闭窗口了。

二、自定义槽函数

假设现在我们想点击清空按键的时候将文本编辑器中的文本全部清除,这就需要自己定义dialog的相关槽函数了。
在这里插入图片描述
右击清空button,选择转到槽函数:
在这里插入图片描述
这是它作为一个pushbutton所拥有的信号,点击OK,会自动跳转到一个c++文件中,这就是关联的槽函数的名称,我们把它复制到自己定义的类中作为一个类方法:
在这里插入图片描述

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): # 这就是自己定义的槽函数
       self.ui.plainTextEdit.clear()

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

运行,单击清空按键就会发现文本被清除了,完美!
在这里插入图片描述

总结

这里我们生成的c++文件其实没用用上,只是为了查看生成的槽函数的名称,其实我们自己也省略了手动关联的部分,比如相对于内置的槽函数,我们自定义的槽函数少了下面的语句:

        self.pushButton_2.clicked.connect(Dialog.accept) # 这里是确认
        self.pushButton.clicked.connect(Dialog.close)   # 这里是取消

这是因为Qt帮我们自动关联了,只要我们命名的槽函数符合某个规范,例如:on_pushButton_3_clicked(self):,命名规则符合on_<object name>_<signal name>_(<signal parameter>)即可,我们注意到上面自动生成的py文件还包含一句:

        self.pushButton_2.clicked.connect(Dialog.accept) # 这里是确认
        self.pushButton.clicked.connect(Dialog.close)   # 这里是取消
        QtCore.QMetaObject.connectSlotsByName(Dialog)  # 这里是自动建立关联

如果没有后面这句代码,那么我们也要向上面一样手动关联:

self.pushButton_3.clicked.connect(Dialog.on_pushButton_3_clicked)
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
Python中的信号函数是在PyQt中的核心机制,用于实现对象之间的通信。与一般的函数不同,函数可以与一个信号关联,在信号被发射时自动执行。信号函数具有以下特点: 1. 一个信号可以连接多个函数,这意味着一个信号可以触发多个函数的执行。 2. 一个信号也可以连接另一个信号,这样可以在一个信号发射时触发另一个信号。 3. 信号的参数可以是任何Python类型,这使得信号可以携带数据并将其传递给函数。 4. 一个函数可以连接到多个信号,这样当任何一个信号被触发时,都会执行该函数。 5. 信号函数的连接方式可以是同步连接或异步连接,具体取决于开发者的需求。 6. 信号函数的连接可能会跨线程,这允许在多线程环境下进行信号的通信。 7. 信号函数的连接可以随时断开,这样之后信号的发射就不会再触发与之关联的函数。 总结来说,Python信号函数是一种强大的机制,可以实现对象之间的灵活交互和通信。通过连接信号函数,可以实现事件驱动的编程,提高代码的可维护性和可扩展性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Python Qt GUI设计信号的使用方法(基础篇—7)](https://blog.csdn.net/m0_38106923/article/details/120190935)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [PyQt5 信号(Signal)与(Slot)](https://blog.csdn.net/u013420428/article/details/128083678)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肆拾伍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值