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函数,就可以对窗体进行操作了,一起试一下吧!


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


目录
相关文章
|
24天前
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
125 67
|
18天前
|
Python
Python中的函数是**一种命名的代码块,用于执行特定任务或计算
Python中的函数是**一种命名的代码块,用于执行特定任务或计算
43 18
|
10天前
|
数据可视化 DataX Python
Seaborn 教程-绘图函数
Seaborn 教程-绘图函数
40 8
|
19天前
|
Python
Python中的函数
Python中的函数
32 8
|
26天前
|
监控 测试技术 数据库
Python中的装饰器:解锁函数增强的魔法####
本文深入探讨了Python语言中一个既强大又灵活的特性——装饰器(Decorator),它以一种优雅的方式实现了函数功能的扩展与增强。不同于传统的代码复用机制,装饰器通过高阶函数的形式,为开发者提供了在不修改原函数源代码的前提下,动态添加新功能的能力。我们将从装饰器的基本概念入手,逐步解析其工作原理,并通过一系列实例展示如何利用装饰器进行日志记录、性能测试、事务处理等常见任务,最终揭示装饰器在提升代码可读性、维护性和功能性方面的独特价值。 ####
|
1月前
|
Python
Python中的`range`函数与负增长
在Python中,`range`函数用于生成整数序列,支持正向和负向增长。本文详细介绍了如何使用`range`生成负增长的整数序列,并提供了多个实际应用示例,如反向遍历列表、生成倒计时和计算递减等差数列的和。通过这些示例,读者可以更好地掌握`range`函数的使用方法。
51 5
|
1月前
|
数据可视化 开发者 Python
Python GUI开发:Tkinter与PyQt的实战应用与对比分析
【10月更文挑战第26天】本文介绍了Python中两种常用的GUI工具包——Tkinter和PyQt。Tkinter内置于Python标准库,适合初学者快速上手,提供基本的GUI组件和方法。PyQt基于Qt库,功能强大且灵活,适用于创建复杂的GUI应用程序。通过实战示例和对比分析,帮助开发者选择合适的工具包以满足项目需求。
124 7
|
1月前
|
测试技术 数据安全/隐私保护 Python
探索Python中的装饰器:简化和增强你的函数
【10月更文挑战第24天】在Python编程的海洋中,装饰器是那把可以令你的代码更简洁、更强大的魔法棒。它们不仅能够扩展函数的功能,还能保持代码的整洁性。本文将带你深入了解装饰器的概念、实现方式以及如何通过它们来提升你的代码质量。让我们一起揭开装饰器的神秘面纱,学习如何用它们来打造更加优雅和高效的代码。
|
1月前
|
弹性计算 安全 数据处理
Python高手秘籍:列表推导式与Lambda函数的高效应用
列表推导式和Lambda函数是Python中强大的工具。列表推导式允许在一行代码中生成新列表,而Lambda函数则是用于简单操作的匿名函数。通过示例展示了如何使用这些工具进行数据处理和功能实现,包括生成偶数平方、展平二维列表、按长度排序单词等。这些工具在Python编程中具有高度的灵活性和实用性。
36 2
|
2月前
|
Python
python的时间操作time-函数介绍
【10月更文挑战第19天】 python模块time的函数使用介绍和使用。
40 4

热门文章

最新文章