【从零开始学习QT】信号和槽

article/2025/7/27 23:48:57

目录

一、信号和槽概述

信号的本质

槽的本质

二、信号和槽的使用

2.1 连接信号和槽

2.2 查看内置信号和槽

2.3 通过 Qt Creator 生成信号槽代码

自定义槽函数

自定义信号

自定义信号和槽

2.4 带参数的信号和槽

三、信号与槽的连接方式

3.1 一对一

(1)一个信号连接一个槽

(2)一个信号连接另一个信号

3.2 一对多

3.3 多对一

四、信号与槽的连接

五、使用 Lambda 表达式定义槽函数


QT专栏:QT_uyeonashi的博客-CSDN博客

一、信号和槽概述

在 Qt 中,用户和控件的每次交互过程称为一个事件。比如 "用户点击按钮" 是一个事件,"用户关闭窗口" 也是一个事件。每个事件都会发出一个信号,例如用户点击按钮会发出 "按钮被点击" 的信号,用户关闭窗口会发出 "窗口被关闭" 的信号。

Qt 中的所有控件都具有接收信号的能力,一个控件还可以接收多个不同的信号。对于接收到的每个信号,控件都会做出相应的响应动作。例如,按钮所在的窗口接收到 "按钮被点击" 的信号后,会做出 "关闭自己" 的响应动作;再比如输入框自己接收到 "输入框被点击" 的信号后,会做出 "显示闪烁的光标,等待用户输入数据" 的响应动作。在 Qt 中,对信号做出的响应动作就称之为槽

信号和槽是 Qt 特有的消息传输机制,它能将相互独立的控件关联起来。比如,"按钮" 和 "窗口"
本身是两个独立的控件,点击 "按钮" 并不会对 "窗口" 造成任何影响。通过信号和槽机制,可以将 "按钮" 和 "窗口" 关联起来,实现 "点击按钮会使窗口关闭" 的效果。

信号的本质

信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时 Qt 对
应的窗口类会发出某个信号,以此对用户的操作做出反应。因此,信号的本质就是事件。如:
• 按钮单击、双击
• 窗口刷新
• 鼠标移动、鼠标按下、鼠标释放
• 键盘输入

那么在 Qt 中信号是通过什么形式呈现给使用者的呢?
• 我们对哪个窗口进行操作, 哪个窗口就可以捕捉到这些被触发的事件。
• 对于使用者来说触发了一个事件我们就可以得到 Qt 框架给我们发出的某个特定信号。
信号的呈现形式就是函数, 也就是说某个事件产生了, Qt 框架就会调用某个对应的信号函数, 通知使用者。

槽的本质

槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的 C++ 函数是一样的,可以定义在类的任何位置( public、protected 或 private ),可以具有任何参数,可以被重载,也可以被直接调用(但是不能有默认参数)。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

说明
(1)信号和槽机制底层是通过函数间的相互调用实现的。每个信号都可以用函数来表示,称为信号函数;每个槽也可以用函数表示,称为槽函数。例如: "按钮被按下" 这个信号可以用 clicked() 函数表示,"窗口关闭" 这个槽可以用 close() 函数表示,假如使用信号和槽机制-

实现:"点击按钮会关闭窗口" 的功能,其实就是 clicked() 函数调用 close() 函数的效果。

(2)信号函数和槽函数通常位于某个类中,和普通的成员函数相比,它们的特别之处在于:
• 信号函数用 signals 关键字修饰,槽函数用 public slots、protected slots 或者 private slots 修饰。signals 和 slots 是 Qt 在 C++ 的基础上扩展的关键字,专门用来指明信号函数和槽函数;
• 信号函数只需要声明,不需要定义(实现),而槽函数需要定义(实现)。

二、信号和槽的使用

2.1 连接信号和槽

在 Qt 中,QObject 类提供了一个静态成员函数 connect() ,该函数专门用来关联指定的信号函数和槽函数。

QObject 是 Qt 内置的父类. Qt 中提供的很多类都是直接或者间接继承自 QObject

connect() 函数原型:

connect (const QObject *sender,const char * signal ,const QObject * receiver ,const char * method ,Qt::ConnectionType type = Qt::AutoConnection )

代码示例: 在窗口中设置一个按钮,当点击 "按钮" 时关闭 "窗口" 

2.2 查看内置信号和槽

系统自带的信号和槽通常是通过 "Qt 帮助文档" 来查询

如上述示例,要查询 "按钮" 的信号,在帮助文档中输入:QPushButton,
• 首先可以在 "Contents" 中寻找关键字 signals,
• 如果没有找到, 继续去父类中查找. 因此我们去他的父类 QAbstractButton 中继续查找关键字signals

这里的 clicked() 就是要找的信号。槽函数的寻找方式和信号一样,只不过它的关键字是 slot 。

2.3 通过 Qt Creator 生成信号槽代码

Qt Creator 可以快速帮助我们生成信号槽相关的代码.

自定义槽函数

所谓的slot就是一个普通的成员函数

自定义一个槽函数,操作过程和自定义一个普通的成员函数,没啥区别

第一种方式:一个简单的代码

第二种方式:

  -> 

QT Creator 直接给我们生成好了一个函数;

在 "widget.h" 头文件中自动添加槽函数的声明;在 "widget.cpp" 中自动生成槽函数定义.

自定义信号

Qwidget :咱们的Widget虽然还没有定义任何信号,由于继承自QWidget和QObject这两类已经提供了一些信号量可以直接使用

所谓的QT信号,本质上也是一个“函数”,Qt 5及更高版本中,槽函数和普通成员函数之间,没啥区别

1. 信号是一类非常特殊的函数,程序员只需要写出函数声明,并告诉Qt这是一个信号即可。这个函数的定义是Qt在编译过程中自动生成的(自动生成的过程,程序员无法干预)

信号在Qt中是特殊的机制,Qt生成的信号函数实现要配合Qt框架做很多既定的操作

2. 作为信号函数,这个函数的返回值必须是void,有没有函数都可以,甚至也可以支持重载

signals:这个也是Qt自己扩展出来的关键字~

qmake的时候调用一些代码的分析/生成工具,扫描到类中包含signals这个关键字的时候,此时就会自动把下面的函数声明认为是信号,并且把这些信号函数自动的生成函数定义

举个栗子:

我们运行之后发现并窗口没有变化

这里qt提供了一个关键字emit,使用 "emit" 关键字发送信号


自定义信号和槽

2.4 带参数的信号和槽

Qt 的信号和槽也支持带有参数, 同时也可以支持重载.
此处我们要求, 信号函数的参数列表要和对应连接的槽函数参数列表一致.
此时信号触发, 调用到槽函数的时候, 信号函数中的实参就能够被传递到槽函数的形参当中.

传参可以起到复用代码的效果;有多个逻辑,逻辑上基本整体一致,但是涉及到的数据不同

就可以通过函数-参数来复用代码,并且在不同的场景中传入不同的参数即可~

举个栗子:

注意:带有参数的信号,要求信号的参数和槽的参数要一致;类型要一直,参数个数要满足信号的参数个数要多于槽的参数个数


三、信号与槽的连接方式

3.1 一对一

主要有两种形式,分别是:一个信号连接一个槽 一个信号连接一个信号

(1)一个信号连接一个槽

举个栗子:

1、在 "widget.h" 中声明信号和槽以及信号发射函数;

2、在 "widget.cpp" 中实现槽函数,信号发射函数以及连接信号和槽;

(2)一个信号连接另一个信号

举个栗子:

在上述示例的基础上,在 "widget.cpp" 文件中添加如下代码:

3.2 一对多

一个信号连接多个槽

举个栗子:

(1)在 "widget.h" 头文件中声明一个信号和三个槽;

(2)在 "widget.cpp" 文件中实现槽函数以及连接信号和槽;

3.3 多对一

多个信号连接一个槽函数

举个栗子:

(1)在 "widget.h" 头文件中声明两个信号以及一个槽;

(2)在 "widget.cpp" 文件中实现槽函数以及连接信号和槽;

四、信号与槽的连接

如果没有disconnect,就会构成一个信号绑定了两个槽函数,触发信号的时候就会两个槽函数都执行

使用disconnect来断开信号的连接,disconnect的使用方式和connect是非常类似的

五、使用 Lambda 表达式定义槽函数

Lambda表达式 的语法格式如下:

[ capture ] ( params ) opt -> ret {
Function body;
};

说明: 

举个栗子:

注意:

lambda为了解决上述问题,引入了“变量捕获”,通过变量捕获,获取到外层作用域中的变量,即将变量名称写到[ ]中

如过变量特别多课以写成[=],这个写法的含义就是把上层作用域中所有的变量名都给捕获进来!

注意lambda在捕获的时候一定要保证对象是可用的(注意生命周期)


总结:信号与槽的优缺点

优点: 松散耦合

信号发送者不需要知道发出的信号被哪个对象的槽函数接收,槽函数也不需要知道哪些信号关联了自己,Qt的信号槽机制保证了信号与槽函数的调用。支持信号槽机制的类或者父类必须继承于 QObject类。

缺点: 效率较低

与回调函数相比,信号和槽稍微慢一些,因为它们提供了更高的灵活性,尽管在实际应用程序中差别不大。通过信号调用的槽函数比直接调用的速度慢约10倍(这是定位信号的接收对象所需的开销;遍历所有关联;编组/解组传递的参数;多线程时,信号可能需要排队),这种调用速度对性能要求不是非常高的场景是可以忽略的,是可以满足绝大部分场景。


本篇完!


http://www.hkcw.cn/article/CLRyMSUGij.shtml

相关文章

教授为选麦种晒到脱皮妻子心疼落泪 客厅变“麦场”

堆满麦穗的客厅里,一位“老农”打着赤膊认真筛选着麦子。河南科技大学农学院教授王林生长年致力于小麦遗传育种研究。每年麦收时节,他家的客厅、阳台甚至书房都变成了他的“麦场”,到处堆满了金黄色的麦子和打包好的麦种。责任编辑:zx0001

印度81人因“同情”巴基斯坦被逮捕 社交媒体发帖引争议

印度阿萨姆邦首席部长萨尔马于6月1日宣布,该邦有81人因“同情”巴基斯坦被警方逮捕。此前,印巴两国因印控克什米尔地区枪击事件发生严重冲突。萨尔马在声明中提到,印度一直在追踪社交媒体上反国家的帖子并采取行动。据当地警方消息,其中一人因为在Instagram上发布巴基斯坦国…

日本北海道附近海域发生5.9级地震 地震频发引关注

北京时间6月2日2时51分,日本北海道附近海域发生5.9级地震,震源深度55公里,震中位于北纬41.80度,东经143.75度。此前,当地时间5月31日17时37分左右,该地区还发生了一次6.1级地震,最大震感为震度4,震源深度20公里。近期,一则关于日本将在7月5日迎来大灾难的预言在社交平…

基于python大数据的音乐可视化与推荐系统

博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,没有什么华丽的语言&#xff0…

力扣HOT100之动态规划:416. 分割等和子集

这道题之前刷过代码随想录,现在只能想起一点点思路,最后还是去看视频了。这道题用二维dp数组或者一维dp数组都可以做,这篇博客把两种思路都讲一下。 二维dp数组做法 原问题可以抽象为:容量为sum / 2的背包能否用数组中的物品填满…

【学习笔记】Sparse Crosscoders for Cross-Layer Features and Model Diffing

Sparse Crosscoders for Cross-Layer Features and Model Diffing Abstract 本说明介绍了稀疏跨编码器(sparse crosscoders),它是一种稀疏自编码器(sparse autoencoders)或transcoders的变体,旨在用于理解叠加中的模型结构。SAEs是在单一层中编码和预测…

Python UV 环境下的 PyKDL 运动学库安装

视频讲解: Python UV 环境下的 PyKDL 运动学库安装 mujoco-learning这个仓库,改成uv管理环境依赖后,原来的一些包有些缺失,比如之前安装的PyKDL,于是把这部分补进来~ 结合《PyKDL 运动学动力学库-安装(源码…

Linux驱动之平台总线

Linux驱动之平台总线 参考视频地址 【北京迅为】嵌入式学习之Linux驱动(第六期_平台总线_全新升级)_基于RK3568_哔哩哔哩_bilibili 平台总线介绍 一、什么是平台总线模型? ​ 平台总线模型也叫platform总线模型。平台总线是Linux系统虚拟…

《Python语言程序设计》2018 第4章第9题3重量和价钱的对比,利用第7章的概念来解答你

利用类来解答这个问题。 pack1, price1 50, 24.59 pack2, price2 25, 11.99class result:def __init__(self,pack,price):self.pack packself.price pricedef set_pack(self):return self.packdef set_price(self):return self.pricedef get_result(self):return self.pric…

Parametric Retrieval Augmented Generation

Parametric Retrieval Augmented Generation 3. Methodology 3.1 Problem Formulation and Overview 文中原始符号数学表示额外解释LLM L L L大模型的简化表示LLM parameters θ \theta θ大模型的参数表示user query q q q用户的输入external corpus K K K K { d 1 , d 2 ,…

8088 单板机 汇编 NMI 中断程序示例 (脱离 DOS 环境)

; ; nmi_demo.asm - 8088 单板机 NMI 中断演示程序 ; 脱离 DOS 环境,直接运行在裸机上 ; ; 硬件配置假设: ; - 8088 CPU 4.77MHz ; - 8259 PIC (可编程中断控制器) ; - 8255 PPI (可编程外设接口) 连接 LED ; - 7 段数码管显示 ; - NMI 按钮连接到 NMI 引脚PORT_P…

HRMS数据模型:解密组织的数字基因库与智能管理引擎

摘要 随着数字化转型浪潮席卷全球,人力资源管理系统(HRMS)正升级为企业的“数字基因库”,承载着组织、岗位与人员的动态管理使命。本文基于创新的“三维动态耦合模型”,系统剖析HRMS数据模型设计理念、关键组件与业务…

Nature|张泽民团队提出CM模型新视角 | 单细胞如何走向系统生态?|细胞模块概念新研究范式

端午节儿童节,假期到了,不知道大家有没有安排出游,去哪里放松、吃到什么特别的美食?长大之后,儿童节就悄悄地从我们的生活中“毕业”了,忙碌中偶尔的童心和好奇,还是要有的。 今天分享最近学习…

题单:最大公约数(辗转相除法)

题目描述 所谓 “最大公约数(GCD)” ,是指所有公约数中最大的那个,例如 12 和 1818 的公约数有 1,2,3,6 ,所以 12 和 18 的最大公约数为 6 。 辗转相除法,又名欧几里德算法(Euclidean Algorit…

75岁薛家燕谈小17岁男友 甜蜜恋情持续12年

近日,75岁的资深艺人薛家燕在接受采访时谈及与小17岁男友Andy的恋情,难掩甜蜜。她表示男友多年来对她一直很好。两人通过朋友介绍相识,最初通过电子邮件交流。薛家燕曾因年龄差距犹豫退缩,担心对方只是一时喜欢,甚至一度提出分手。但Andy以真诚打动了她,两人相恋12年,尽…

女子骑电动三轮闯卡强行上高速 收费站工作人员尽力拦截未果

5月31日,有网友在抖音平台发布了一段行车记录仪视频。视频显示,在陕西省渭南市华州收费站,一名女子骑着电动三轮车强行闯卡驶上了高速公路。根据视频内容,当天下午6点45分左右,这名女子骑着电动三轮车紧跟在一辆汽车后面。收费站工作人员发现后,试图让她退回去,但她并未…

新规施行拒绝刷脸有依据了 保护个人信息安全

近年来,刷脸技术在识别个人信息方面的应用日益广泛,从小区门禁、酒店登记到交通出行和金融支付,在经济社会的各个领域几乎都能见到“刷脸”技术的应用。然而,这种便捷性背后也隐藏着不容忽视的风险。为规范人脸识别技术的使用并保护个人信息安全,国家互联网信息办公室和公…

河南水库水位下降现千佛石窟 佛像多有残损引发关注

近日,河南省鹤壁市淇县夺丰水库水位下降后,一处千佛石窟显露出来,引发网友关注。该石窟洞壁布满佛像,但不少佛头和手臂几乎都消失不见。淇县县委宣传部一负责人表示,这处石窟当地人一直都知道,民间称其为天竺石窟或千佛洞。该负责人曾在十多年前两次进入石窟参观。夺丰水…

郑钦文回应晋级:再打两盘都没问题 体力充沛信心足

郑钦文鏖战3盘,耗时2小时47分钟,以2-1击败萨姆索诺娃,晋级法网女单8强,刷新了个人在法网的最佳战绩。赛后接受采访时,她表示自己还有很多能量,甚至开玩笑说如果女子比赛有五盘制,她再打两盘也没问题。这场比赛非常激烈,对手发挥出色,给郑钦文施加了很大压力,她在底线…

当地称瘦弱骆驼主人此前已养死一只 另一只现状堪忧

近日,多名网友在社交平台上发帖称,在福建省福州市平潭县流水镇路边发现一只疑似被遗弃的骆驼。这只骆驼体型瘦弱,趴伏在地上,毛发稀疏,周围没有任何遮蔽,引起了广泛关注。6月1日,一名当地居民表示,5月9日她曾路过该路段,看到有两只骆驼趴在路边;今天早上再去查看时,…