Qt Lambda表达式的运用

Posted cpp_learner

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt Lambda表达式的运用相关的知识,希望对你有一定的参考价值。

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,会报错。

以上是关于Qt Lambda表达式的运用的主要内容,如果未能解决你的问题,请参考以下文章

Qt 连接:使用 Lambda 表达式重置传递的 int 变量(奇怪)

ubuntu下对Qt工程进行deb打包发布

Lambda表达式

Lambda表达式

lambda表达式,写一个接口,运用一下

Qt5中的lambda表达式和使用lambda来写connect