Qt Lambda表达式的运用

本文介绍了Qt5中使用Lambda表达式增强信号槽功能,展示了如何通过不同捕获方式实现灵活的异步代码执行。通过实例详细解释了Lambda表达式的各种捕获模式,包括不捕获、传值、传引用以及混合捕获等,并演示了如何在信号槽连接中调用类内部成员函数和私有变量。
摘要由CSDN通过智能技术生成

Qt5中有全新的信号与槽语法,在Qt4基础上提高了信号与槽的灵活性,允许使用任意函数作为槽函数。但如果想更好地执行异步代码,连函数名都不想定义,则可通过Lambda表达式达到这个目的。Lambda表达式是C++11新增加的特性。

Lambda表达式引用符

引用符说明
[]不捕获任何外部变量
[=]以传值的方式捕获所有的外部变量
[&]以传引用的方式捕获所有外部变量
[x,&y]x以传值的方式捕获,y以传引用的方式捕获
[=,&x]x以引用的方式捕获,其余外部变量以传值的方式捕获
[&,x]x以传值的方式捕获,其余外部变量则以传引用的方式捕获
[this]可以调用类内部成员函数与私有成员变量

下面是例子,通过connect函数进行使用

1.新建一个类,然后添加几个成员函数和成员变量作为测试使用
2.创建信号
3.在构造函数中进行测试

1. [] 不捕获任何外部变量

connect(this, &TestFile::Lambada, this, [](){ 
	qDebug() << "Lambda表达式!";
});

2. [=] 以传值的方式捕获所有的外部变量

connect(this, &TestFile::Lambada, this, [=]() {
	// a = 20; b = 30; 因为是传值,所以不能改变外部的值,否则会报错!
	qDebug() << "[=]:a = " << a << "\tb = " << b;
});

3. [&] 以传引用的方式捕获所有外部变量

connect(this, &TestFile::Lambada, this, [&]() {
	// 可以以修改外部值,修改后,外部值也会一起被修改
	a = 30; b = 40;
	qDebug() << "[&]:a = " << a << "\tb = " << b;
});

4. [a,&b] a以传值的方式捕获,b以传引用的方式捕获

connect(this, &TestFile::Lambada, this, [a, &b]() {
	// b可以修改,a不可以修改
	/*a = 30;*/ b = 30;
	qDebug() << "[a,&b]:a = " << a << "\tb = " << b;
});

5. [=, &a] a以引用的方式捕获,其余外部变量以传值的方式捕获

connect(this, &TestFile::Lambada, this, [=, &a]() {
	// a可以修改,b不可以修改
	a = 0; /*b = 30;*/
	qDebug() << "[=, &a]:a = " << a << "\tb = " << b;
});

6. [&,a] a以传值的方式捕获,其余外部变量则以传引用的方式捕获

connect(this, &TestFile::Lambada, this, [&, a]() {
	// b可以修改,a不可以修改
	/*a = 0;*/ b = 30; 
	qDebug() << "[&, a]:a = " << a << "\tb = " << b;
});

7. [this] 可以调用类内部成员函数与私有成员变量

connect(this, &TestFile::Lambada, this, [this]() {
	c = 20;	// 类成员私有变量
	qDebug() << "[this]:c = " << c;

	// 类成员函数
	testQFile();
	testQFileInfo();
	testQTextStream();
});

代码:

.h 文件

#pragma once

#include <QtWidgets/QWidget>
#include "ui_TestFile.h"

#pragma execution_character_set("utf-8") // qt支持显示中文

class TestFile : public QWidget {
	Q_OBJECT

public:
	TestFile(QWidget *parent = Q_NULLPTR);


private:
	void testQFile();
	void testQFileInfo();
	void testQTextStream();


signals:
	void Lambada();

private:
	Ui::TestFileClass ui;
	int c;
};

.cpp 文件

#include "TestFile.h"

#include <QFile>
#include <QDebug>
#include <QString>
#include <QFileInfo>
#include <QDateTime>

TestFile::TestFile(QWidget *parent)
	: QWidget(parent) {
	ui.setupUi(this);

	int a = 10;
	int b = 20;

	// [] 不捕获任何外部变量
	connect(this, &TestFile::Lambada, this, [](){ 
		qDebug() << "Lambda表达式!";
	});


	// [=] 以传值的方式捕获所有的外部变量
	connect(this, &TestFile::Lambada, this, [=]() {
		// a = 20; b = 30; 因为是传值,所以不能改变外部的值,否则会报错!
		qDebug() << "[=]:a = " << a << "\tb = " << b;
	});


	// [&] 以传引用的方式捕获所有外部变量
	connect(this, &TestFile::Lambada, this, [&]() {
		// 可以以修改外部值,修改后,外部值也会一起被修改
		a = 30; b = 40;
		qDebug() << "[&]:a = " << a << "\tb = " << b;
	});

	
	// [a,&b] a以传值的方式捕获,b以传引用的方式捕获
	connect(this, &TestFile::Lambada, this, [a, &b]() {
		// b可以修改,a不可以修改
		/*a = 30;*/ b = 30;
		qDebug() << "[a,&b]:a = " << a << "\tb = " << b;
	});


	// [=, &a] a以引用的方式捕获,其余外部变量以传值的方式捕获
	connect(this, &TestFile::Lambada, this, [=, &a]() {
		// a可以修改,b不可以修改
		a = 0; /*b = 30;*/
		qDebug() << "[=, &a]:a = " << a << "\tb = " << b;
	});


	// [&,a] a以传值的方式捕获,其余外部变量则以传引用的方式捕获
	connect(this, &TestFile::Lambada, this, [&, a]() {
		// b可以修改,a不可以修改
		/*a = 0;*/ b = 30; 
		qDebug() << "[&, a]:a = " << a << "\tb = " << b;
	});


	// [this] 可以调用类内部成员函数与私有成员变量
	connect(this, &TestFile::Lambada, this, [this]() {
		c = 20;
		qDebug() << "[this]:c = " << c;

		testQFile();
		testQFileInfo();
		testQTextStream();
	});

	emit Lambada();
	qDebug() << "a = " << a << "\tb = " << b;

}


// QFile
void TestFile::testQFile() {
	// 测试
}

// QFileInfo
void TestFile::testQFileInfo() {
	// 测试
}

// QTextStream
void TestFile::testQTextStream() {
	// 测试
}

运行截图:
在这里插入图片描述


总结
Lambda表达式就是这么简单,只需注意表达式引入符就好。另外,括号里也是可以带参数的,因为我定义的信号没有带参,所以使用的使用也不可以带参。

注意事项
捕获列表不允许变量重复传递,如[=,a]则以传值方式捕获所有变量,又重复捕获a,会报错。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值