Qt学习(三)—— lambda表达式

2023-11-20

lambda表达式

lambda 表达式是 C++ 11 新增的新特性,用于定义并创建匿名的函数对象,在 Qt 中配合信号一起使用。使用lambda表达式的好处在于不用定义槽函数,也不用指定信号接收者。

为了使用 lambda 表达式,需要在项目文件中配置 C++ 11 的规则。

//.pro文件中
CONFIG += C++11

lambda表达式的基本构成

[ 函数对象参数 ] ( 操作符重载函数参数 ) mutable 或 exception -> 返回值 { 函数体 }

① 函数对象参数;

[],标识一个Lambda的开始,这部分必须存在,不能省略函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this,也就是自身所有成员变量)。函数对象参数有以下形式:

  ※ 空。没有使用任何函数对象参数。

  ※ =。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this,也就是自身所有成员变量),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。

  ※ &。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this,也就是自身所有成员变量),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。

  ※ this。函数体内可以使用Lambda所在类中的成员变量。

  ※ a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。

  ※ &a。将a按引用进行传递。

  ※ a, &b。将a按值进行传递,b按引用进行传递。

  ※ =,&a, &b。除a和b按引用进行传递外,其他参数都按值进行传递。

  ※ &, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。

int m = 0, n = 0;

[=] (int a) mutable { m = ++n + a; }(4);

      [&] (int a) { m = ++n + a; }(4);

      [=,&m] (int a) mutable { m = ++n + a; }(4);

      [&,m] (int a) mutable { m = ++n + a; }(4);

      [m,n] (int a) mutable { m = ++n + a; }(4);

      [&m,&n] (int a) { m = ++n + a; }(4);

② 操作符重载函数参数;

标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。

③ 可修改标示符;

mutable声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。

④ 错误抛出标示符;

exception声明,这部分也可以省略。exception声明用于指定函数抛出的异常,如抛出整数类型的异常,可以使用throw(int)

⑤ 函数返回值;

->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。

⑥ 是函数体;

    {},标识函数的实现,这部分不能省略,但函数体可以为空。

下面用一个小实验来体会一下lambda表达式的用法

1) 函数对象参数为空时,在函数体内对变量进行操作。

#include "MainWidget.h"
#include "ui_MainWidget.h"
#include <QPushButton>
#include "SubWidget.h"
#include <QDebug>

MainWidget::MainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWidget)
{
    ui->setupUi(this);

    //这部分代码略过

    QPushButton *b3=new QPushButton(this);
    b3->setText("lambda表达式");
    b3->move(70,70);
    int a=0;
    connect(b3,&QPushButton::released,[](){    //函数对象参数为空
        b3->setText("lambda生效");
    });
}

MainWidget::~MainWidget()
{
    delete ui;
}

结果: 

可以知道要想在函数体内对变量进行操作,就必须在函数对象参数列表中传入这个变量。当指定函数对象参数为"="后,程序正常运行。但如果函数体内只是进行一个字符串的输出,没有使用到b3,即使函数对象参数为空,程序也会正常运行。

2) 函数对象参数为"="时,在对局部变量a进行修改。

#include "MainWidget.h"
#include "ui_MainWidget.h"
#include <QPushButton>
#include "SubWidget.h"
#include <QDebug>

MainWidget::MainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWidget)
{
    ui->setupUi(this);

    //这部分代码略过

    QPushButton *b3=new QPushButton(this);
    b3->setText("lambda表达式");
    b3->move(70,70);
    int a=0;
    connect(b3,&QPushButton::released,[=](){    //函数对象参数为空
        b3->setText("lambda生效");
        a=1;
    });
}

MainWidget::~MainWidget()
{
    delete ui;
}

结果:

可以知道不能够修改函数对象参数指定为值传递的对象的值,但如果想要修改,可以用mutable关键字。

3) 用mutable关键字修饰lambda表达式,分别在函数体内和函数体外输出变量a的值。

#include "MainWidget.h"
#include "ui_MainWidget.h"
#include <QPushButton>
#include "SubWidget.h"
#include <QDebug>

MainWidget::MainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWidget)
{
    ui->setupUi(this);

    //这部分代码略过

    QPushButton *b3=new QPushButton(this);
    b3->setText("lambda表达式");
    b3->move(70,70);
    int a=0;
    connect(b3,&QPushButton::released,[=](){    //函数对象参数为空
        b3->setText("lambda生效");
        a=1;
        qDebug()<<a;
    });
    qDebug()<<a;
}

MainWidget::~MainWidget()
{
    delete ui;
}

结果: 

可以知道加了关键字mutable之后,在lambda表达式函数体内是可以改变由值传递方式传入的参数的副本的值,注意是改变副本的值,参数本身的值不会改变。

P.S:当使用引用传值时,最好不要对指针变量进行操作,会导致程序异常。

4) 用操作符重载函数参数可以用来接收信号的返回值。

#include "MainWidget.h"
#include "ui_MainWidget.h"
#include <QPushButton>
#include "SubWidget.h"
#include <QDebug>

MainWidget::MainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWidget)
{
    ui->setupUi(this);

    //这部分代码略过

    QPushButton *b3=new QPushButton(this);
    b3->setText("lambda表达式");
    b3->move(70,70);
    int a=0;
    connect(b3,&QPushButton::clicked,[=](bool isclicked)mutable{
        b3->setText("lambda生效");
        a=1;
        qDebug()<<a;
        b1.setText("局部成员可以访问");
        qDebug()<<isclicked;
    });
    qDebug()<<a;
}

MainWidget::~MainWidget()
{
    delete ui;
}

P.S:不是所有信号都有返回值。比如released就没有。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt学习(三)—— lambda表达式 的相关文章

  • 如何为 Windows 构建静态 Qt 库并将其与 Qt Creator 一起使用

    我已经下载了以下 Qt 源 http download qt nokia com qt source qt everywhere opensource src 4 7 3 zip http download qt nokia com qt
  • 安装J语言的JQt IDE,出现错误

    我一直按照这里的说明进行操作 http code jsoftware com wiki System Installation Linux http code jsoftware com wiki System Installation L
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • 是否可以在 Qt Creator 中将 Qt 样式表与升级的小部件一起使用?

    我正在尝试使用 Qt 样式表对标准小部件进行一些重大的重新设计 因此 在为不同的小部件手动完成大部分工作之后 objectName选择器 我决定以某种方式对类似的小部件进行分组 例如我有多个QFrames其作用类似于内部表单中的标题 我希望
  • 如何访问Loader的sourceComponent中的QML对象?

    我可能需要读取或写入的一些属性Loader s sourceComponent来自一些外部函数 访问该房产的方式是什么x里面的对象的Loader s sourceComponent import QtQuick 2 0 Item width
  • 为什么总是在 mouseDoubleClickEvent 之前调用 mousePressEvent

    请考虑以下代码 include
  • 将 UTC 格式的 QDateTime 转换为本地系统时间

    我从这样的字符串构造 QDateTime QDateTime date QDateTime fromString 2010 10 25T10 28 58 570Z yyyy MM ddTHH mm ss zzzZ 我知道date是 UTC
  • 常量类成员、赋值运算符和 QList

    请确认我是否正确并告诉我是否有更好的解决方案 我了解具有常量成员的对象 例如int const width 无法由编译器隐式创建的合成赋值运算符处理 但是 QList 我想 std list 也是如此 需要一个有效的赋值运算符 因此 当我想
  • Qt:删除富文本

    对于明文有QFontMetrics elideText https doc qt io qt 5 qfontmetrics html elidedText https doc qt io qt 5 qfontmetrics html eli
  • 扩展 TabViewStyle styleData

    我目前正在尝试找到一种更好的方法来执行此操作 将图标添加到选项卡 现在 我正在放弃 styleData title 以包含图标源 但如果能够扩展 styleData 就更好了 这样我就可以包含其他自定义属性 这是我当前的黑客 Tab tit
  • QWinTaskbarProgress 不会显示

    我使用的是windows7和Qt5 3 0 我在 MainWindow 的构造函数中添加了以下内容 但任务栏上没有显示任何内容 我错过了什么 QWinTaskbarProgress pTaskbarProgress new QWinTask
  • 如何在 Qt simple 上解密/加密某些字符串(例如密码)

    这是我得到的 Qt SDK版本4 6 2 视窗XP 问题 我怎样才能简单地加密和简单地加密QString价值 我需要它能够将一些加密的字符串保存到 INI 文件中 并在重新打开应用程序后将字符串加密为正常的密码字符串值 PS 我正在寻找简单
  • QObject多重继承

    我正在尝试在 C Qt 类中使用 mix 来提供一大堆具有通用接口的小部件 该接口是以这样的方式定义的 如果它被定义为其他小部件类的基类 那么小部件本身将具有这些信号 class SignalInterface public QObject
  • Qt 创建者 4.8.4。 Windows 7 - 64 位安装

    我在 QT 方面遇到了一些困难 我需要在学校使用它来完成一些 GUI 应用程序 我最近完成了以下步骤 1 mingw get inst 20120426 exefrom 来源锻造 http sourceforge net projects
  • 从 Qt 更改屏幕分辨率?

    我想更改屏幕分辨率 然后使用一个 ActiveX 控件 Flash 播放器 进入全屏 显然 仅适用于 Windows 的解决方案就可以了 有 Qt api 吗 还是我需要深入研究 winapi 如果是这样 我该在哪里查找 关键字 谢谢您的帮
  • cmake 找不到 Qt4

    由于4 8 0已经发布 我重新安装了Qt 现在我也想使用cmake 为了使 cmake 工作 我记得必须添加 mingw bin 文件夹 QtSDK Desktop Qt 4 7 3 到Qt4 7 3中的PATH 所以我猜测在中会有一个类似
  • 如何使用 qt 库中的调试符号为 qt 5.5 创建开发 shell

    我有一个开发外壳buildInputs条目包括qt55 qtbase 这很好用 今天 我在 qt 库中发生了段错误 我想要带有调试符号的 qt 库 我看了一下nixpkgs pkgs development libraries qt 5 5
  • 无法将 [未定义] 分配给 QColor

    我正在使用 Qt 5 11 构建 运行代码 代码中有QML风格如下 Button style delegate Component id enabledButtonStyle ButtonStyle padding top 0 paddin
  • 如何从键盘为 QTableWidget 创建信号?

    我有一张桌子 可以通过左 右 上 下按钮在里面移动 现在 当我停留在某个单元格并按空格键时 我需要创建一个信号 该信号还应该带来该单元格的坐标 我尝试使用 QTableWidget 的标准信号 但它不起作用 我该如何解决这个问题 创建一个单
  • Qt QML MenuItem iconSource不显示

    我有一个非常简单的设置只是为了说明问题 import QtQuick Controls 1 4 import QtQuick Window 2 2 ApplicationWindow visible true width 640 heigh

随机推荐

  • 利用input上传图片以及文件视频音频等

    这里说的input指的就是我们常用的
  • unity中创建询问弹出窗口

    在开发过程中进程会遇到需要弹出一个窗口询问用户是否进行的操作 今天就来制作一个这样弹出窗口 然后根据弹出窗口的选择内容不同进行不同的操作 本例中主要是为了删除一个数据 而在删除数据操作前需要得到用户的一个确认操作 这里面主要用到了Notif
  • 一个超级棒的VUE流程设计器--easy-flow开箱即用

    今天小编推荐一款流程设计器easy flow easy flow基于VUE ElementUI JsPlumb的流程设计器 通过 vuedraggable 插件来实现节点拖拽 功能介绍 支持拖拽添加节点 点击线进行设置条件 支持给定数据加载
  • JSON介绍及代码示例

    了解json JSON是什么 JSON是JavaScript Object Notation的缩写 它是一种数据交换格式 在JSON出现之前 大家一直用XML来传递数据 因为XML是一种纯文本格式 所以它适合在网络上交换数据 XML本身不算
  • MFC ListControl

    1 ListControl的基本创建 基本设置 m ListCtrl DeleteAllItems m ListCtrl InsertColumn 0 T NBA m ListCtrl InsertColumn 1 T Final Cham
  • office2010 卸载出现“安装程序找不到ProPlus.ww\ProPsWW.cab 请浏览正确的安装源的错”解决方法

    笔者在换电脑后想卸载office2010安装office2016 但是卸载的过程中遇到了上述问题就记录一下自己的解决方案 1 强制删除officeX对应的文件夹 然后使用toolkit工具清理即可 笔者是通过这种方法解决的 2 应该也可以使
  • C++STL之deque容器

    概述 上一篇我们讲过queue容器 它是一个单向的队列 只能从尾部插入 头部删除 而本节讲的deque容器 它是一个双向的队列 在头尾均可以调用插入与删除 并且支持迭代器和迭代器随机访问 这是它与queue的最大区别 实际上 deque容器
  • c++读取文件

    include
  • 7z命令行加密文件夹和文件名

    因为有时候需要将非常机密的东西上传到网盘 毕竟网盘也不一定安全 而每次都鼠标点添加密码很麻烦 然后就用命令行脚本弄快 电脑安装7zip 在你要压缩的文件夹打开命令行 7z a r pABC12345 mhe on test 7z a 添加f
  • 5 款最棒的 Vue 移动端 UI 组件库 - 特别针对国内使用场景推荐

    本文完整版 最棒的 Vue 移动端 UI 组件库 特别针对国内使用场景推荐 Vue 移动端 UI 组件库推荐 Vant 3 有赞移动 UI 组件库 支持 Vue 3 微信小程序 支付宝小程序 Cube UI 滴滴出行移动端 UI 库 质量可
  • 关于直流电源纹波和噪声的测量的分析和介绍

    电源纹波和噪声的定义PARD periodicand random deviation 1 电源纹波 Power Ripple 直流电压 电流中 叠加在直流稳定量上的交流分量 用电压和电流的均方根值 mVrms mArms 或峰峰值 mVp
  • 优秀LOGO的六大特质

    1 识别性 大多数的设计师认为 识别性是最容易在艺术设计和商业设计上发生冲突的地方 很多设计师都抱怨客户没有审美 喜欢平庸的LOGO设计 而一些客户认为设计师缺乏对公司和产品的理解 不懂营销 归根到底 无论设计师的设计多么创新 多么独特 始
  • 【word】错误!文档中没有指定样式的文字。 1

    问题 给文档中的图片插入题注时 报错 错误 文档中没有指定样式的文字 1 解决办法 光标定位到错误信息上 单击右键 选择 编辑域 在弹出的 域 对话框中 左侧的 域名 列表中选择 StyleRef 在右侧的 样式名 列表中选择 列表段落
  • Fabric private data入门实战

    Hyperledger Fabric private data是1 2版本引入的新特性 fabric private data是利用旁支数据库 SideDB 来保存若干个通道成员之间的私有数据 从而在通道之上又提供了一层更灵活的数据保护机制
  • VSCode中配置命令行参数

    VSCode中配置命令行参数 在跑程序调试的时候 可以直接使用脚本运行程序 这个时候调试代码只能用pdb 我觉得不太习惯 而且感觉不是很好 所以想这能不能将运行程序的脚本中的命令直接配置到vscode上 就有了这篇记录 正常vscode D
  • DHCP配置实战

    1 DHCP简介 DHCP dynamic host configuration protocol 动态的主机配置协议 基于TCP P的网络 DHCP减少了重新配置计算机IP地址的工作量 在TCP P网络中 IP地址的规划与分配是一件重要而
  • Java手写广度优先搜索和案例拓展

    Java手写广度优先搜索和案例拓展 手写必要性 手写实现广度优先搜索算法主要有以下几个必要性 理解算法原理 通过手写实现广度优先搜索算法 能够深入理解算法的原理和运行机制 这有助于我们更好地理解广度优先搜索的核心思想和优势 并能应用于解决其
  • pa皮安级电流检测电路

    1 芯片 ad8602 lmc6062 2 电路
  • Eclipse中targetlm2e-wtplweb-resources\META-1(Click for details)解决办法

    targetlm2e wtplweb resources META 1 Click for details 系统找不到指定的路径 解决办法 最近总是发现我的eclipse里面的maven项目总是报错误时不时地出现 然后我自己更新一下mave
  • Qt学习(三)—— lambda表达式

    lambda表达式 lambda 表达式是 C 11 新增的新特性 用于定义并创建匿名的函数对象 在 Qt 中配合信号一起使用 使用lambda表达式的好处在于不用定义槽函数 也不用指定信号接收者 为了使用 lambda 表达式 需要在项目