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

Qt的信号与槽 文章目录

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

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

此篇作为信号与槽的总结篇

信号和槽的其他说明

1、信号与槽的断开

使用disconnect即可完成断开,disconnect的用法和connect基本不一致

实际上大部分情况下,把信号和槽连接上之后就不必在管了,所以disconnect使用的比较少。主动断开往往是把信号重新绑定到另一个槽函数上

2、Qt4版本信号与槽的连接

Qt4中的connect用法和Qt5相比更复杂,需要搭配SIGNAL和SLOT宏来完成,而且缺少必要的函数类型的检查,使代码更容易出错

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

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

(1)Qt4版本信号与槽函数连接的优缺点

  • 优点:参数直观
  • 缺点:参数类型不做检测

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

Qt5 在 Qt4 的基础上提高了信号与槽的灵活性,允许使用任意函数作为槽函数。但如果想方便的编写槽函数,比如在编写函数时连函数名都不想定义,则可以通过 Lambda 表达式来达到这个目的。

Lambda 表达式是 C++11 增加的特性。C++11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。

Lambda 表达式的语法格式如下

cpp 复制代码
[ capture ] ( params ) opt -> ret { 
    Function body;
};

(1)局部变量引入方式【】

\] : 标识一个 Lambda 表达式的开始。不可省略 ![](https://i-blog.csdnimg.cn/direct/cbca11009dee4f23a9a38ccc35fef436.png) 说明: * 由于使用引用方式捕获对象会有局部变量释放了而 Lambda 函数还没有被调用的情况。如果执行 Lambda函数,那么引用传递方式捕获进来的局部变量的值不可预知。所以绝大多数场合使用的形式为:\[=\] () { } * 早期版本的 Qt,若要使用 Lambda 表达式,要在 ".pro" 文件中添加: CONFIG += C++11 因为 Lambda 表达式是 C++11 标准提出的。Qt5 以上的版本无需手动添加,在新建项目时会自动添加。 ![](https://i-blog.csdnimg.cn/direct/ac746a2c0a2c4b13bc9cc659a4549622.png) Lambda 表达式的使用: ![](https://i-blog.csdnimg.cn/direct/3c7884315e6745d989ea79a2f2b72972.png) 以 \[=\] 方式传递,外部的所有变量在 Lambda 表达式中都可以使用 ![](https://i-blog.csdnimg.cn/direct/2cf50c331cee4be5a52ed42d28f36286.png) 以 \[a\] 方式传递,在 Lambda 表达式中只能使用传递进来的 a ![](https://i-blog.csdnimg.cn/direct/b14a88de6dde4a5193919582945ed339.png) Lambda 表达式除了可以按照值得方式来捕获变量 \[=\],还可以按照引用得方式来捕获 \[\&\](但 Qt 中很少这样写),捕获到的变量一般就是各自控件得指针。指针变量按照值传递或者引用来传递都无所谓。如果选择按照引用来传递,还得更关注这个引用得变量本身的生命周期。 #### (2)函数参数() (params) 表示 Lambda函数对象接收的参数,类似于函数定义中的小括号表示函数接收的参数类型和个数。参数可以通过按值(如:(int a,int b))和按引用(如:(int \&a,int \&b))两种方式进行传递。函数参数部分可以省略,省略后相当于无参的函数。 ![](https://i-blog.csdnimg.cn/direct/9785336e2cbd430099e9b1f9b168a3cb.png) #### (3)选项Opt **Opt** 部分是可选项,最常用的是 **mutable**声明,这部分可以省略。 Lambda 表达式外部的局部变量通过值传递进来时,其默认是 **const**,所以不能修改这个局部变量的拷贝,加上 mutable 就可以修改。 ![](https://i-blog.csdnimg.cn/direct/db288c7a1f5043d89bf111faf8cf82f6.png) #### (4)Lambda表达式的返回值 可以指定 Lambda表达式返回值类型。如果不指定返回值类型,则编译器会根据代码实现为函数推导⼀个返回类型。如果没有返回值,则可忽略此部分。 ![](https://i-blog.csdnimg.cn/direct/cdb53d79a4694122ae2c5773ca49f9fa.png) ![](https://i-blog.csdnimg.cn/direct/713fd81afb0f4837a2eab116e0df7b79.png) #### (5)Lambda表达式的函数体{} Lambda 表达式的函数体部分与普通函数体一致。用 { } 标识函数的实现,不能省略,但函数体可以为空。 ![](https://i-blog.csdnimg.cn/direct/cb0afdcd6a194cadbd221fba51d81826.png) #### (6)槽函数使用Lambda表达式来实现 A. 点击按钮关闭窗口 ![](https://i-blog.csdnimg.cn/direct/7c571a871d424ce9b4a5782ae595fe63.png) B. 当 "connect" 函数第三个参数为 "this" 时,第四个参数使用 Lambda表达式时,可以省略掉 "this" ![](https://i-blog.csdnimg.cn/direct/bb28f5f1ce5b49328d5c064d2972e3fc.png) ### 4、信号与槽的优缺点 #### (1)优点:松散耦合 > 信号发送者不需要知道发出的信号被哪个对象的槽函数接收,槽函数也不需要知道哪些信号关联了自己,Qt 的信号槽机制保证了信号与槽函数的调用。支持信号槽机制的类或者父类必须继承于 QObject 类。 #### (2)缺点:效率较低 > 与回调函数相比,信号和槽稍微慢一些,因为它们提供了更高的灵活性,尽管在实际应用程序中差别不大。通过信号调用的槽函数比直接调用的速度慢约 10 倍(这是定位信号的接收对象所需的开销;遍历所有关联;编组 / 解组传递的参数;多线程时,信号可能需要排队),这种调用速度对性能要求不是非常高的场景是可以忽略的,是可以满足绝大部分场景。 ⼀个客户端程序中,最慢的环节往往是 "人"。假设本身基于回调的方式是 10us,使用信号槽的方式是 100us。对于使用程序的人来说,是感知不到的。

相关推荐
happymaker06262 小时前
VueCli标准化工程中的组件通信操作
开发语言·前端·javascript
ySq0REx012 小时前
.NET 10 & C# 14 New Features 新增功能介绍-.NET CLI工具改进
开发语言·c#·.net
Howrun7772 小时前
C++ 项目测试全指南:从 0 基础到落地实操
开发语言·c++·log4j
小灰灰搞电子2 小时前
Qt UI 线程详解-阻塞与解决方案
开发语言·qt·ui
追光的蜗牛丿2 小时前
C++传递参数时什么情况下传递引用
开发语言·javascript·c++
Pocker_Spades_A2 小时前
Python快速入门专业版(五十六)——爬虫会话管理:Cookie与Session原理及实战(保持登录状态)
开发语言·爬虫·python
MwEUwQ3Gx2 小时前
深入理解 Java Deque 的设计哲学
java·开发语言·python
张人玉2 小时前
C#程序设计编程二维码识别程序
开发语言·c#·二维码
森G2 小时前
41、数据库---------事件系统
c++·qt