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。对于使用程序的人来说,是感知不到的。

相关推荐
xieliyu.5 分钟前
Java算法精讲:双指针(三)
java·开发语言·算法
CryptoPP1 小时前
快速对接东京证券交易所API数据:实战指南与代码示例
开发语言·人工智能·windows·python·信息可视化·区块链
ZC跨境爬虫1 小时前
跟着 MDN 学JavaScript day_7:数学运算与逻辑判断实战测试
开发语言·前端·javascript·学习·ecmascript
阳区欠2 小时前
【LangChain】LLM基础介绍
开发语言·python·langchain
Jinkxs2 小时前
Java 跨域14-Java 与区块链(Hyperledger)集成
java·开发语言·区块链
晨曦中的暮雨3 小时前
Golang速通(Javaer版)
java·开发语言·后端·golang
小小编程路4 小时前
Python 还有容器类型互转、进制转换、字符编码转换
开发语言·windows·python
qeen874 小时前
【C++】类与对象之类的默认成员函数(二)
android·c语言·开发语言·c++·笔记·学习
CRMEB系统商城4 小时前
CRMEB多商户系统(Java)v2.3公测版发布
java·开发语言·人工智能·小程序·开源·php
动能小子ohhh4 小时前
DocForge平台的设计与开发--文件上传接口的实现
开发语言·人工智能·python·langchain·ocr·fastapi