QT->信号与槽详解下(概述、使用、自定义、连接方式、其他说明)

一、自定义信号和槽

1、基本语法

在Qt中,允许自定义信号的发送接收方以及接收方,即可以自定义信号函数和槽函数。但是对于自定义信号的信号函数和槽函数有一定的书写规则。

Qt中如果要让某个类能够使用信号槽(可以在类中定义信号和槽函数),则必须要在类最开始的地方写下Q_OBJECT宏(这个宏可以展开很多代码)。如果不加上这个宏,那么编译的时候就会报错。这个宏不需要我们自己手动添加,一般Qt create会帮助我们自动生成

(1)自定义信号函数书写规范

自定义信号在实际开发中很少需要用到,Qt内置的信号就足以应付大部分的开发场景

所谓Qt的信号,本质上也就是一个函数,在Qt5以及更高的版本中,槽函数和普通的成员函数之间没有什么差别。但是,信号是一类非常特殊的函数,我们只要写出函数声明,并告诉Qt这是一个信号即可。这个函数的定义是Qt在编译过程中自动生成的

1、自定义信号函数必须写到"signals"下

2、返回值为void,只需要声明,不需要实现

3、可以有参数,也可以发送重载

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

(2)自定义槽函数书写规范

所谓的自定义一个槽函数,其操作规律和自定义一个普通成员函数没有什么区别

1、早期的Qt版本要求槽函数必须写到"public slots"下,但是现在高级版本的Qt允许写到类的"public"作用域中或者全局下

2、返回值为void,需要声明,也需要实现

3、可以有参数,可以发生重载

槽声明的两种写法:

此处的slots是Qt自己扩展的关键字,不是C++标准中的写法。qmake构建Qt项目时,就会调用专门的扫描器,扫描代码中特定的关键字(比如slots),基于关键字自动生成一大堆相关代码

(3)发送信号

使用**"emit"**关键字发送信号。"emit"是一个空的宏。"emit"其实是可选的,没有什么含义,只是为了提醒开发人员

(4)示例

A.一

a.在widget.h中声明自定义的信号和槽

b.在widget.cpp中实现槽函数,并且关联信号和槽

首先关联信号和槽,一旦检测到信号发送之后就会立刻执行关联的槽函数。反之,若先发射信号,此时还没有关联槽函数,当信号发射之后槽函数就不会响应

B.二------当老师说"上课了",学生们就"回到座位,开始学习"

在源文件中新建两个类,一个是老师类,一个是学生类:首先选中项目名称,鼠标右键------>"add new..."

点击 add new 之后,出现如下界面

选择"choose"出现如下界面

注意:在Qt中新建类时,要选择新建类的父类

显然,当前项目中还没有什么类适合做新类的父类,同时新的类也不是一个"窗口"或者"控件",这种请款一般选择QObject作为基类。这样做的好处是这个新类的对象可以搭配Qt的对象树机制,便于对象的正确释放

选择"下一步",出现如下见面

对于"学生类"以上述同样的方式进行添加,添加完成之后,项目目录新增文件如下:

在 student.h 中声明槽函数:

在 widget.h 中实例化 "老师类对象" 和 "学生类对象":

在 student.cpp 中实现槽函数:

在 widget.cpp 中连接自定义信号和槽:

运行结果如下图所示:

C. 三 ------ 老师点击 "按钮" 触发学生上课

运行结果如下图所示:

2、带参数的信号和槽

Qt的信号槽也支持带有参数,同时也可以支持重载。要求:信号函数的参数列表要和对应连接的槽函数参数列表一致。(一致主要是要求类型,个数如果不一致也可以,但要求信号的参数个数比槽的参数个数多)

此时信号触发,调用到槽函数的时候,信号函数中的实参就能够被传递到槽函数的形参中。通过这样的机制就可以让信号给槽传递数据了

(1)重载信号槽

A. 在 "widget.h" 头文件中声明重载的信号函数以及重载的槽函数

B. 在 "Widget.cpp" 文件实现重载槽函数以及连接信号和槽

C. 执行结果

(2)信号槽参数列表匹配规则

A. 在 "widget.h" 头文件中声明信号和槽函数

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

其实信号的参数个数可以多于槽函数的参数个数,但是槽的参数个数不能多于信号参数个数。但是实际开发中最好还是保持参数个数也能匹配⼀致。

(3)信号的参数个数多于槽函数的参数个数

A. 在 "widget.h" 头文件中声明信号和槽函数

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

二、信号与槽的连接方式

1、一对一

主要有两种形式,分别是

1、一个信号连接一个槽

2、一个信号连接一个信号

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

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

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

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

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

2、一对多

一个信号连接多个槽:

在 "widget.h" 头文件中声明一个信号和三个槽:

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

3、多对一

多个信号连接一个槽函数

在 "widget.h" 头文件中声明两个信号以及一个槽:

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

4、多对多

多个信号连接多个槽函数:

在 "widget.h" 头文件中声明三个信号以及三个槽:

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

实际上,随着程序员经验越来越多,在GUI开发的过程中,"多对多"其实是个"伪需求",实际开发会很少用到,绝大部分情况来说,"一对一"就够用了

信号槽存在的意义:

  • 解耦合(写代码追求"高内聚,低耦合")
  • 多对多(非常类似于Mysql中的"多对多")
相关推荐
Chester_19992 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
EXI-小洲3 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
会周易的程序员4 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
机器视觉知识推荐、就业指导4 小时前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan4 小时前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
小灰灰搞电子4 小时前
完全驾驭 Qt 与数据库:C++ ORM 框架 QxOrm 原理与实践指南
数据库·c++·qt
QT界面美化性能优化4 小时前
QT+AI:使用AI技术为QT应用程序赋能
c++·人工智能·qt·opencv·qt教程·qt6.3
m0_695251494 小时前
Qt MaintenanceTool 使用国内镜像加速下载(超详细教程)
开发语言·qt
大衛說5 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
可乐鸡翅yeah_7 小时前
hls.js 内存泄漏实战排查,直播 M3U8 长时间播放异常定位方案
开发语言·javascript·python·django·ecmascript·m3u8·m3u8在线