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

news/2024/11/17 0:38:58/

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, QtWidgetsclass 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: ignoreself.btnClose.clicked.connect(Dialog.close) # type: ignoreQtCore.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.translateDialog.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 sysapp = 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_Dialogclass 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 QmyDialogapp = QApplication(sys.argv)#创建GUI应用程序
mainform = QmyDialog()#创建主窗体
mainform.show()#显示主窗体
sys.exit(app.exec())

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

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

顺便点个赞鼓励一下作者吧⸜(●˙▾˙●)⸝⸜(●˙▾˙●)⸝


http://www.ppmy.cn/news/754225.html

相关文章

寸照尺寸

[常识]一寸照片是多大? 一寸2.5*3.5cm295*413像素 1寸照片 平时都用寸来表示照片的规格但很多朋友包括我在内都还搞不清楚这1 寸照片到底是多大二寸照片为何不是一寸照片的两倍大一寸是多少像素等问 题现在就把常用的照片尺寸、对应的大小厘米及数码相机分…

开源项目推荐 【SkyEyeSystem】

大家好,今天向大家推荐一个开源项目——SkyEyeSystem。 这是一个基于Spring Boot的全网热点爬虫项目,旨在提供全面而准确的全网热搜数据。 关于项目 SkyEyeSystem通过定时任务间隔10min爬取全网热搜数据。目前包括的平台有: 微博热搜B站热…

【Redis】缓存穿透、缓存击穿、缓存雪崩的原因及解决方案

文章目录 一、缓存穿透1.1 产生原因1.2 解决方法接口校验对空值进行缓存使用布隆过滤器实时监控 二、缓存雪崩2.2 解决方法将失效时间分散开给业务添加多级缓存构建缓存高可用集群使用锁或者队列的方式设置缓存标记 三、缓存击穿3.2 解决方法使用互斥锁”提前“使用互斥锁 / 逻…

电商扣减库存_电商后台产品经理宝典

作者:清水红牙搬运 by A小蚊子丨ID:xiaowenzileyuan想了解更多,欢迎关注公众号“A小蚊子(xiaowenzileyuan)”,更多精彩内容、知识大礼包等你发现。欢迎将此文分享给更多朋友,大家共同精进电商架构 电商架构(图电商核心模块(图商品中心 管理SKU:最小库存单位管理SPU:…

Kotlin之类型系统

Kotlin之类型系统 可空类型 在任何类型后加“?”表示该变量可为空。val a: Int? null。 安全的调用 使用“?.”进行安全调用。实现方式:仍旧使用if判空。student?.name。 合并运算符 使用“?:”运算符。 val result a ?: 1 非空断言 使用“!!”操作…

是德频谱仪N9020A维修报错维修-安泰维修

近期,有客户送来一台是德N9020A频谱仪,故障表现为报错。工程师接到仪器后,对其进行故障检测。 经过工程师检查后,开机发现自检失败,报错LO Unlock,无基线。 经检测,仪器前端板损坏,造…

【维修类别】

需求分析 维修类别功能界面如下: 维修类别大致就是故障种类,它是丛属班组的,目前系统中在用的班组只有两个【电仪和设备】 除了从属于班组,维修类别还和具体的设备种类有关,(比如加弹机,染色机…

维修行业迫切需要O2O?“报修一站通”寻遍上海为各类水货、无主、超保产品对接维修网点

以下文章转自 36氪 http://www.36kr.com/p/205702.html, 同时也可以向一直关心我的朋友解释下过去一年多我的去向。:) 城市发展给我们带来了现代化的生活,同时也带来了某些不便。过去手机坏了、冰箱需要加氟时,一出家…