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 表达式的开始。不可省略

说明:

  • 由于使用引用方式捕获对象会有局部变量释放了而 Lambda 函数还没有被调用的情况。如果执行 Lambda函数,那么引用传递方式捕获进来的局部变量的值不可预知。所以绝大多数场合使用的形式为:= () { }
  • 早期版本的 Qt,若要使用 Lambda 表达式,要在 ".pro" 文件中添加: CONFIG += C++11 因为 Lambda 表达式是 C++11 标准提出的。Qt5 以上的版本无需手动添加,在新建项目时会自动添加。

Lambda 表达式的使用:

= 方式传递,外部的所有变量在 Lambda 表达式中都可以使用

a 方式传递,在 Lambda 表达式中只能使用传递进来的 a

Lambda 表达式除了可以按照值得方式来捕获变量 =,还可以按照引用得方式来捕获 \&(但 Qt 中很少这样写),捕获到的变量一般就是各自控件得指针。指针变量按照值传递或者引用来传递都无所谓。如果选择按照引用来传递,还得更关注这个引用得变量本身的生命周期。

(2)函数参数()

(params) 表示 Lambda函数对象接收的参数,类似于函数定义中的小括号表示函数接收的参数类型和个数。参数可以通过按值(如:(int a,int b))和按引用(如:(int &a,int &b))两种方式进行传递。函数参数部分可以省略,省略后相当于无参的函数。

(3)选项Opt

Opt 部分是可选项,最常用的是 mutable声明,这部分可以省略。

Lambda 表达式外部的局部变量通过值传递进来时,其默认是 const,所以不能修改这个局部变量的拷贝,加上 mutable 就可以修改。

(4)Lambda表达式的返回值

可以指定 Lambda表达式返回值类型。如果不指定返回值类型,则编译器会根据代码实现为函数推导⼀个返回类型。如果没有返回值,则可忽略此部分。

(5)Lambda表达式的函数体{}

Lambda 表达式的函数体部分与普通函数体一致。用 { } 标识函数的实现,不能省略,但函数体可以为空。

(6)槽函数使用Lambda表达式来实现

A. 点击按钮关闭窗口

B. 当 "connect" 函数第三个参数为 "this" 时,第四个参数使用 Lambda表达式时,可以省略掉 "this"

4、信号与槽的优缺点

(1)优点:松散耦合

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

(2)缺点:效率较低

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

⼀个客户端程序中,最慢的环节往往是 "人"。假设本身基于回调的方式是 10us,使用信号槽的方式是 100us。对于使用程序的人来说,是感知不到的。

相关推荐
用户805533698031 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner1 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz6 天前
QML Hello World 入门示例
qt
xcyxiner9 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner10 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner10 天前
DicomViewer (添加模型类)3
qt
xcyxiner11 天前
DicomViewer (目录调整) 2
qt
xcyxiner11 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00613 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术13 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript