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


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


目录
相关文章
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
642 2
|
算法 Java Docker
(Python基础)新时代语言!一起学习Python吧!(三):IF条件判断和match匹配;Python中的循环:for...in、while循环;循环操作关键字;Python函数使用方法
IF 条件判断 使用if语句,对条件进行判断 true则执行代码块缩进语句 false则不执行代码块缩进语句,如果有else 或 elif 则进入相应的规则中执行
1812 1
|
Java 数据处理 索引
(numpy)Python做数据处理必备框架!(二):ndarray切片的使用与运算;常见的ndarray函数:平方根、正余弦、自然对数、指数、幂等运算;统计函数:方差、均值、极差;比较函数...
ndarray切片 索引从0开始 索引/切片类型 描述/用法 基本索引 通过整数索引直接访问元素。 行/列切片 使用冒号:切片语法选择行或列的子集 连续切片 从起始索引到结束索引按步长切片 使用slice函数 通过slice(start,stop,strp)定义切片规则 布尔索引 通过布尔条件筛选满足条件的元素。支持逻辑运算符 &、|。
556 0
|
设计模式 缓存 监控
Python装饰器:优雅增强函数功能
Python装饰器:优雅增强函数功能
457 101
|
缓存 测试技术 Python
Python装饰器:优雅地增强函数功能
Python装饰器:优雅地增强函数功能
382 99
|
存储 缓存 测试技术
Python装饰器:优雅地增强函数功能
Python装饰器:优雅地增强函数功能
710 98
|
缓存 Python
Python中的装饰器:优雅地增强函数功能
Python中的装饰器:优雅地增强函数功能
|
Python
Python 函数定义
Python 函数定义
1142 155
|
算法 安全 数据安全/隐私保护
Python随机数函数全解析:5个核心工具的实战指南
Python的random模块不仅包含基础的随机数生成函数,还提供了如randint()、choice()、shuffle()和sample()等实用工具,适用于游戏开发、密码学、统计模拟等多个领域。本文深入解析这些函数的用法、底层原理及最佳实践,帮助开发者高效利用随机数,提升代码质量与安全性。
1549 0
|
数据挖掘 数据处理 C++
Python Lambda:从入门到实战的轻量级函数指南
本文通过10个典型场景,详解Python中Lambda匿名函数的用法。Lambda适用于数据处理、排序、条件筛选、事件绑定等简洁逻辑,能提升代码简洁性和开发效率。同时提醒避免在复杂逻辑中过度使用。掌握Lambda,助你写出更高效的Python代码。
853 0

推荐镜像

更多