PyQt---------信号与槽函数的关系

简介: PyQt---------信号与槽函数的关系

1.信号(Signal)


信号是在特定情况下被发射的一种通告。举例:

PushButton 的信号是鼠标单击时发射的 clicked 信号

2.槽(Slot)

对信号相应的函数。举例:

QWidget 有一个槽函数,功能是关闭窗口

3.信号与槽的关系

一个信号可以关联多个槽函数

一个信号可以关联其他信号

信号的参数可以是任何 Python 数据类型

一个槽函数可以和多个信号关联

关联可以是直接的(同步)或排队的(异步)

可以在不同的线程之间建立关联 (信号与槽可以断开关联)

关于槽函数与信号的实例:

在PyQt中做以下窗口:

可以实现在字体下划下划线,斜体,变粗,以及字体变色


窗口链接我放这里:


链接:https://pan.baidu.com/s/1LzahreskBrSH8JfYZeaQjQ

提取码:cyss


注:


我在这里重新做过排序



设置信号和槽


在这里我们设置对话框类 Qdialog 内置槽函数

accept():关闭对话框,表示肯定的选择,例如“确定”

reject():关闭对话框,表示否定的选择,例如“取消”

close():关闭对话框

点击右上边的Edit Signals

点击确定按钮


点击clicked(),接着点击accept()

同理点击关闭按钮,点击clicked(),close()



就可以在Signal and Slots Editor中看到



在Eric中创建该项目



这里就是刚刚建好的信号与槽的关联


(1)为做演示,我在Ui_Dialog中添加了一些代码,用于在TextEdit中显示文字


代码如下:


# Form implementation generated from reading ui file 'D:\cys\Dialog.ui'
#
# Created by: PyQt6 UI code generator 6.5.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again.  Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(471, 452)
        self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
        self.verticalLayout.setObjectName("verticalLayout")
        self.groupBox1 = QtWidgets.QGroupBox(parent=Dialog)
        self.groupBox1.setTitle("")
        self.groupBox1.setObjectName("groupBox1")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox1)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.chkBoxUnder = QtWidgets.QCheckBox(parent=self.groupBox1)
        self.chkBoxUnder.setChecked(False)
        self.chkBoxUnder.setObjectName("chkBoxUnder")
        self.horizontalLayout.addWidget(self.chkBoxUnder)
        self.chkBoxItalic = QtWidgets.QCheckBox(parent=self.groupBox1)
        self.chkBoxItalic.setObjectName("chkBoxItalic")
        self.horizontalLayout.addWidget(self.chkBoxItalic)
        self.chkBoxBold = QtWidgets.QCheckBox(parent=self.groupBox1)
        self.chkBoxBold.setObjectName("chkBoxBold")
        self.horizontalLayout.addWidget(self.chkBoxBold)
        self.verticalLayout.addWidget(self.groupBox1)
        self.groupBox = QtWidgets.QGroupBox(parent=Dialog)
        self.groupBox.setTitle("")
        self.groupBox.setObjectName("groupBox")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.radioBlack = QtWidgets.QRadioButton(parent=self.groupBox)
        self.radioBlack.setObjectName("radioBlack")
        self.horizontalLayout_2.addWidget(self.radioBlack)
        self.radioRed = QtWidgets.QRadioButton(parent=self.groupBox)
        self.radioRed.setObjectName("radioRed")
        self.horizontalLayout_2.addWidget(self.radioRed)
        self.radioBlue = QtWidgets.QRadioButton(parent=self.groupBox)
        self.radioBlue.setObjectName("radioBlue")
        self.horizontalLayout_2.addWidget(self.radioBlue)
        self.verticalLayout.addWidget(self.groupBox)
        self.plainTextEdit = QtWidgets.QPlainTextEdit(parent=Dialog)
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.verticalLayout.addWidget(self.plainTextEdit)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem)
        self.btnClear = QtWidgets.QPushButton(parent=Dialog)
        self.btnClear.setObjectName("btnClear")
        self.horizontalLayout_3.addWidget(self.btnClear)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem1)
        self.btnOK = QtWidgets.QPushButton(parent=Dialog)
        self.btnOK.setObjectName("btnOK")
        self.horizontalLayout_3.addWidget(self.btnOK)
        self.btnClose = QtWidgets.QPushButton(parent=Dialog)
        self.btnClose.setObjectName("btnClose")
        self.horizontalLayout_3.addWidget(self.btnClose)
        self.verticalLayout.addLayout(self.horizontalLayout_3)
        self.retranslateUi(Dialog)
        self.btnOK.clicked.connect(Dialog.accept) # type: ignore
        self.btnClose.clicked.connect(Dialog.close) # type: ignore
        QtCore.QMetaObject.connectSlotsByName(Dialog)
        Dialog.setTabOrder(self.chkBoxUnder, self.chkBoxItalic)
        Dialog.setTabOrder(self.chkBoxItalic, self.chkBoxBold)
        Dialog.setTabOrder(self.chkBoxBold, self.radioBlack)
        Dialog.setTabOrder(self.radioBlack, self.radioRed)
        Dialog.setTabOrder(self.radioRed, self.radioBlue)
        Dialog.setTabOrder(self.radioBlue, self.plainTextEdit)
        Dialog.setTabOrder(self.plainTextEdit, self.btnClear)
        Dialog.setTabOrder(self.btnClear, self.btnClose)
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.chkBoxUnder.setText(_translate("Dialog", "Underline"))
        self.chkBoxItalic.setText(_translate("Dialog", "Italic"))
        self.chkBoxBold.setText(_translate("Dialog", "Bold"))
        self.radioBlack.setText(_translate("Dialog", "Black"))
        self.radioRed.setText(_translate("Dialog", "Red"))
        self.radioBlue.setText(_translate("Dialog", "Blue"))
        self.btnClear.setText(_translate("Dialog", "清空"))
        self.btnOK.setText(_translate("Dialog", "确定"))
        self.btnClose.setText(_translate("Dialog", "关闭"))
   
    def do_setTextEdit(self, Dialog):
        self.plainTextEdit.setPlainText("Beautiful is bestter than ugly.")
        self.plainTextEdit.appendPlainText("Explicit is better than implicit.")
        self.plainTextEdit.appendPlainText("Simple is better than complex.")
        self.plainTextEdit.appendPlainText("Complex is better than complicated.")
        self.plainTextEdit.appendPlainText("Flat is better than nested.")
        self.plainTextEdit.appendPlainText("Sparse is better than dense.")
   
       
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec())

注:在Ui_Dialog中实现信号与槽关联的代码:


QtCore.QMetaObject.connectSlotsByName(Dialog)


他的功能是搜索 Dialog 窗体上的所有从属组件,将匹配的信号和槽函数关联起来。


只有符合命名规则的槽函数才会被匹配。不符合命名规则的函数不能自动与信号关联


2)创建myDialog.py


按照 界面与业务逻辑分离且界面独立封装的方式 定义一个类 QmyDialog,保存为myDialog.py。

函数代码如下:

import sys
from PyQt6.QtWidgets import QApplication, QDialog
from PyQt6.QtCore import pyqtSlot
from PyQt6.QtGui import QPalette
from PyQt6.QtCore import Qt
from Ui_Dialog import Ui_Dialog
class QmyDialog(QDialog):
    def __init__(self, parent=None):
#在 QmyDialog 的构造函数__init__中创建了窗体类的实例对象 self.ui,并调用了
#setupUi()函数
        super().__init__(parent)#调用父类构造函数,创建窗体
        self.ui=Ui_Dialog()#创建UI对象
        self.ui.setupUi(self)#构造UI界面
        self.ui.do_setTextEdit(self)
        self.ui.radioBlack.clicked.connect(self.do_setTextColor)
        self.ui.radioRed.clicked.connect(self.do_setTextColor)
        self.ui.radioBlue.clicked.connect(self.do_setTextColor)
       
    def on_btnClear_clicked(self):
        self.ui.plainTextEdit.clear()
       
    def on_chkBoxBold_toggled(self, checked):
        font=self.ui.plainTextEdit.font()
        font.setBold(checked)
        self.ui.plainTextEdit.setFont(font)
   
    def on_chkBoxUnder_clicked(self):
        checked=self.ui.chkBoxUnder.isChecked()
        font=self.ui.plainTextEdit.font()
        font.setUnderline(checked)
        self.ui.plainTextEdit.setFont(font)
       
    @pyqtSlot(bool) #修饰符指定参数类型,用于overload的信号    
    def on_chkBoxItalic_clicked(self, checked):
        font=self.ui.plainTextEdit.font()
        font.setItalic(checked)
        self.ui.plainTextEdit.setFont(font)
   
    def do_setTextColor(self):
        plet=self.ui.plainTextEdit.palette()
        if(self.ui.radioBlack.isChecked()):
            plet.setColor(QPalette.ColorRole.Text, Qt.GlobalColor.black)
        elif(self.ui.radioRed.isChecked()):
            plet.setColor(QPalette.ColorRole.Text, Qt.GlobalColor.red)
        elif(self.ui.radioBlue.isChecked()):
            plet.setColor(QPalette.ColorRole.Text, Qt.GlobalColor.blue)
        self.ui.plainTextEdit.setPalette(plet)
           
       
if __name__=="__main__":#用于当前窗体测试
    app=QApplication(sys.argv)#创建GUI应用程序
    form=QmyDialog()#创建窗体
    form.show()
    sys.exit(app.exec())


对代码的解释:

on_btnClear_clicked这类,按钮对应的槽函数:


点击clicked()



接着,复制这个函数名,在myDialog中编写代码,其他按钮也是类似操作




注意:对overload型信号的处理有所不同


在 Qt Creator 中为 Italic 复选框设置槽函数,选择 clicked(bool)


记下函数名,他是带参数的



注意有一个 clicked(),还有一个 clicked(bool)。这两个都是 clicked 信号。 默认情况下,

connectSlotsByName 只会关联默认的不带参数的 clicked 信号,不会关联带参数的

clicked(bool)信号。

要解决这个问题,需要使用 @pyqtSlot 修饰符 ,将函数的参数类型声明清楚,例如:

@pyqtSlot(bool) #修饰符指定参数类型,用于overload的信号    
    def on_chkBoxItalic_clicked(self, checked):
        font=self.ui.plainTextEdit.font()
        font.setItalic(checked)
        self.ui.plainTextEdit.setFont(font)

同时要新增import模块


from PyQt6.QtCore import pyqtSlot



对于颜色的设置要实现设置颜色的三个 RadioButton 按钮的 clicked()信号与同一个槽函数关联


我们添加如下自定义槽函数

def do_setTextColor(self):
        plet=self.ui.plainTextEdit.palette()
        if(self.ui.radioBlack.isChecked()):
            plet.setColor(QPalette.ColorRole.Text, Qt.GlobalColor.black)
        elif(self.ui.radioRed.isChecked()):
            plet.setColor(QPalette.ColorRole.Text, Qt.GlobalColor.red)
        elif(self.ui.radioBlue.isChecked()):
            plet.setColor(QPalette.ColorRole.Text, Qt.GlobalColor.blue)
        self.ui.plainTextEdit.setPalette(plet)

同时在构造函数中关联信号和槽函数

self.ui.radioBlack.clicked.connect(self.do_setTextColor)
        self.ui.radioRed.clicked.connect(self.do_setTextColor)
        self.ui.radioBlue.clicked.connect(self.do_setTextColor)

这样就可以实现按按钮变换颜色了

(3)创建appMain.py

myDialog.py 可以当作主程序直接运行,但是建议单独编写一个主程序文件 appMain.py。

该文件的功能是创建应用程序和主窗体,然后显示主窗体,并开始运行应用程序。

appMain.py 将 myDialog.py 文件的测试运行部分单独拿出来作为一个文件。

当一个应用程序有多个窗体,并且窗体之间有数据传递时,appMain.py 负责创建应用程序

的主窗体并运行起来,这样使整个应用程序的结构更清晰

代码如下:

import sys
from PyQt6.QtWidgets import QApplication
from myDialog import QmyDialog
app = QApplication(sys.argv)#创建GUI应用程序
mainform = QmyDialog()#创建主窗体
mainform.show()#显示主窗体
sys.exit(app.exec())

运行appMain函数,就可以对窗体进行操作了,一起试一下吧!


创作不易,如果其中有错误尽管私信我哦~💖💖💖💖💖


目录
相关文章
|
1月前
|
Python
【python从入门到精通】-- 第五战:函数大总结
【python从入门到精通】-- 第五战:函数大总结
66 0
|
29天前
|
Python
Python之函数详解
【10月更文挑战第12天】
Python之函数详解
|
30天前
|
存储 数据安全/隐私保护 索引
|
18天前
|
数据可视化 开发者 Python
Python GUI开发:Tkinter与PyQt的实战应用与对比分析
【10月更文挑战第26天】本文介绍了Python中两种常用的GUI工具包——Tkinter和PyQt。Tkinter内置于Python标准库,适合初学者快速上手,提供基本的GUI组件和方法。PyQt基于Qt库,功能强大且灵活,适用于创建复杂的GUI应用程序。通过实战示例和对比分析,帮助开发者选择合适的工具包以满足项目需求。
62 7
|
20天前
|
测试技术 数据安全/隐私保护 Python
探索Python中的装饰器:简化和增强你的函数
【10月更文挑战第24天】在Python编程的海洋中,装饰器是那把可以令你的代码更简洁、更强大的魔法棒。它们不仅能够扩展函数的功能,还能保持代码的整洁性。本文将带你深入了解装饰器的概念、实现方式以及如何通过它们来提升你的代码质量。让我们一起揭开装饰器的神秘面纱,学习如何用它们来打造更加优雅和高效的代码。
|
22天前
|
弹性计算 安全 数据处理
Python高手秘籍:列表推导式与Lambda函数的高效应用
列表推导式和Lambda函数是Python中强大的工具。列表推导式允许在一行代码中生成新列表,而Lambda函数则是用于简单操作的匿名函数。通过示例展示了如何使用这些工具进行数据处理和功能实现,包括生成偶数平方、展平二维列表、按长度排序单词等。这些工具在Python编程中具有高度的灵活性和实用性。
|
25天前
|
Python
python的时间操作time-函数介绍
【10月更文挑战第19天】 python模块time的函数使用介绍和使用。
27 4
|
26天前
|
存储 Python
[oeasy]python038_ range函数_大小写字母的起止范围_start_stop
本文介绍了Python中`range`函数的使用方法及其在生成大小写字母序号范围时的应用。通过示例展示了如何利用`range`和`for`循环输出指定范围内的数字,重点讲解了小写和大写字母对应的ASCII码值范围,并解释了`range`函数的参数(start, stop)以及为何不包括stop值的原因。最后,文章留下了关于为何`range`不包含stop值的问题,留待下一次讨论。
19 1
|
1月前
|
索引 Python
Python中的其他内置函数有哪些
【10月更文挑战第12天】Python中的其他内置函数有哪些
15 1
|
26天前
|
安全 数据处理 数据安全/隐私保护
python中mod函数怎么用
通过这些实例,我们不仅掌握了Python中 `%`运算符的基础用法,还领略了它在解决实际问题中的灵活性和实用性。在诸如云计算服务提供商的技术栈中,类似的数学运算逻辑常被应用于数据处理、安全加密等关键领域,凸显了基础运算符在复杂系统中的不可或缺性。
18 0