qt-C++笔记之使用QtConcurrent异步地执行槽函数中的内容,使其不阻塞主界面

news2024/9/20 5:55:19

qt-C++笔记之使用QtConcurrent异步地执行槽函数中的内容,使其不阻塞主界面

code review!

参考博文:
qt-C++笔记之使用QtConcurrent异步地执行槽函数中的内容,使其不阻塞主界面
qt-C++笔记之QThread使用

文章目录

  • qt-C++笔记之使用QtConcurrent异步地执行槽函数中的内容,使其不阻塞主界面
    • 1.QtConcurrent::run基本用法
      • 基本用法
        • 启动一个全局函数或静态成员函数
        • 使用 Lambda 表达式
        • 启动类的成员函数
      • 指定执行的线程
      • 使用返回值
      • 注意事项
    • 2.代码1:槽函数定义——>QtConcurrent::run(Lambda表达式)——>全局函数
    • 3.代码2:槽函数定义——>QtConcurrent::run(Lambda表达式)——>全局函数
    • 4.代码3:槽函数定义——>QtConcurrent::run(this,&类名::成员函数)
    • 5.代码4:槽函数定义——>QtConcurrent::run(Lambda表达式[this]{执行内容})
    • 6.上述例程的test.pro

1.QtConcurrent::run基本用法

QtConcurrent::run 是 Qt 框架中一个非常有用的函数,用于在不同的线程中异步执行函数或者成员函数,这样可以避免阻塞主线程,提高应用程序的响应性。这个函数是 Qt 并发编程模块的一部分,使用前需要包含头文件 <QtConcurrent>

基本用法

QtConcurrent::run 可以启动任何可调用的对象,包括普通函数、类成员函数以及 lambda 表达式。它返回一个 QFuture<T> 对象,你可以使用这个对象来查询任务的状态或结果。

启动一个全局函数或静态成员函数
#include <QtConcurrent>

void myFunction(int arg1, double arg2) {
    // 处理函数
}

int main() {
    QFuture<void> future = QtConcurrent::run(myFunction, 1, 2.0);
}
使用 Lambda 表达式
#include <QtConcurrent>

int main() {
    auto lambda = [] (int value) {
        // 一些处理
    };
    QFuture<void> future = QtConcurrent::run(lambda, 42);
}
启动类的成员函数
#include <QtConcurrent>

class MyClass {
public:
    void myMemberFunction(int arg) {
        // 处理函数
    }
};

int main() {
    MyClass myObject;
    QFuture<void> future = QtConcurrent::run(&MyClass::myMemberFunction, &myObject, 123);
}

指定执行的线程

默认情况下,QtConcurrent::run 使用全局线程池来执行任务。但是,你也可以指定一个自定义的 QThreadPool 来运行任务。

#include <QtConcurrent>

void myFunction() {
    // 函数实现
}

int main() {
    QThreadPool pool;
    pool.setMaxThreadCount(2);  // 设置线程池大小

    QFuture<void> future = QtConcurrent::run(&pool, myFunction);
    future.waitForFinished();  // 等待任务完成
}

使用返回值

如果被调用的函数有返回值,你可以通过 QFuture<T> 来获取这个值。

#include <QtConcurrent>

int computeValue() {
    return 42;
}

int main() {
    QFuture<int> future = QtConcurrent::run(computeValue);
    int result = future.result();  // 获取结果
    return result;
}

注意事项

  1. 线程安全:确保你传递给 QtConcurrent::run 的函数是线程安全的,特别是当你在多个线程中访问共享数据时。
  2. 资源管理:当你在多线程环境中工作时,需要特别注意资源管理和数据同步。
  3. 生命周期管理:确保所有 QtConcurrent::run 使用的对象在任务执行期间保持有效。

2.代码1:槽函数定义——>QtConcurrent::run(Lambda表达式)——>全局函数

运行
在这里插入图片描述

#include <QApplication>
#include <QPushButton>
#include <QMainWindow>
#include <QtConcurrent>

// 假设这是一个耗时的函数
void heavyFunction() {
    // 模拟耗时操作,例如计算或数据处理
    for (int i = 0; i < 100000000; i++) {
        double x = i * 0.001;
        x = x / 2.0;
    }
}

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        // 创建按钮
        QPushButton *pushButton = new QPushButton("Run Heavy Function", this);
        pushButton->setGeometry(100, 50, 200, 50);

        // 连接按钮的点击信号到相应的槽
        connect(pushButton, &QPushButton::clicked, this, &MainWindow::on_pushButton_clicked);
    }

public slots:
    void on_pushButton_clicked() {
        // 使用 QtConcurrent 运行重耗时函数
        QtConcurrent::run([=] {
            heavyFunction();
        });
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MainWindow w;
    w.show();

    return app.exec();
}

#include "main.moc"  // 确保包含 moc 文件以处理 QObject 的元信息

3.代码2:槽函数定义——>QtConcurrent::run(Lambda表达式)——>全局函数

运行
在这里插入图片描述

#include <QApplication>
#include <QPushButton>
#include <QtConcurrent>

// 假设的耗时函数
void heavyFunction() {
    // 模拟耗时操作,例如进行复杂计算
    for (int i = 0; i < 1000000; ++i) {
        // 模拟计算
    }
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QPushButton button("Run Heavy Function");
    button.resize(200, 50);
    button.show();

    // 连接按钮的点击信号到一个 lambda 表达式,该表达式异步执行 heavyFunction
    QObject::connect(&button, &QPushButton::clicked, []() {
        QtConcurrent::run([]{
            heavyFunction();
        });
    });

    return app.exec();
}

4.代码3:槽函数定义——>QtConcurrent::run(this,&类名::成员函数)

运行
在这里插入图片描述

#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QMutex>
#include <QtConcurrent>

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        // 设置主窗口的大小
        this->setFixedSize(400, 300);

        // 创建一个按钮,并设置其显示文本和父窗口
        QPushButton *button = new QPushButton("Run Heavy Function", this);
        button->setGeometry(100, 100, 200, 50);

        // 连接按钮的点击信号到相应的槽函数
        connect(button, &QPushButton::clicked, this, &MainWindow::on_pushButton_clicked);
    }

    ~MainWindow() {}

private slots:
    void on_pushButton_clicked() {
        QtConcurrent::run(this, &MainWindow::heavyFunction);
    }

private:
    void heavyFunction() {
        // 锁定互斥锁以安全访问成员变量
        mutex.lock();
        // 操作共享数据
        sharedData++;
        mutex.unlock();

        // 执行其他耗时操作
    }

    int sharedData = 0;  // 一个示例成员变量
    QMutex mutex;        // 互斥锁保护成员变量
};

#include "main.moc"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MainWindow w;
    w.show();

    return app.exec();
}

5.代码4:槽函数定义——>QtConcurrent::run(Lambda表达式[this]{执行内容})

运行
在这里插入图片描述

#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QMutex>
#include <QtConcurrent>

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        // 设置主窗口的大小
        this->setFixedSize(400, 300);

        // 创建一个按钮,并设置其显示文本和父窗口
        QPushButton *button = new QPushButton("Run Heavy Function", this);
        button->setGeometry(100, 100, 200, 50);

        // 连接按钮的点击信号到相应的槽函数
        connect(button, &QPushButton::clicked, this, &MainWindow::on_pushButton_clicked);
    }

    ~MainWindow() {}

private slots:
    void on_pushButton_clicked() {
        // 使用 lambda 表达式在后台线程上运行代码
        QtConcurrent::run([this] {
            // 锁定互斥锁以安全访问成员变量
            mutex.lock();
            // 操作共享数据
            sharedData++;
            mutex.unlock();

            // 执行其他耗时操作
        });
    }
private:
    int sharedData = 0;  // 一个示例成员变量
    QMutex mutex;        // 互斥锁保护成员变量
};

#include "main.moc"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MainWindow w;
    w.show();

    return app.exec();
}

6.上述例程的test.pro

TEMPLATE = app
TARGET = qt_test
INCLUDEPATH += .

# Add more modules by appending them here
QT += core gui concurrent

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

SOURCES += main.cpp

HEADERS +=

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1697281.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

23种设计模式顺口溜

口诀&#xff1a; 原型 抽风 &#xff0c;单独 建造 工厂 &#xff08;寓意&#xff1a;&#xff08;这里代指本来很简单的东西&#xff0c;却要干工厂这里复杂的业务&#xff09; 抽风&#xff1a;抽象工厂单独&#xff1a;单例桥代理组合享元适配器&#xff0c;&#xff0…

【SpringBoot】SpringBoot中防止接口重复提交(单机环境和分布式环境)

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 &#x1f33c;前言 &#x1f512;单机环境下防止接口重复提交 &#x1f4d5;导入依赖 &#x1f4c2;项目结构 &#x1f680;创建自定义注解 ✈创建AOP切面 &#x1f697;创建Conotroller &#x1f4bb;分布…

mysql实战——Mysql8.0高可用之双主+keepalived

一、介绍 利用keepalived实现Mysql数据库的高可用&#xff0c;KeepalivedMysql双主来实现MYSQL-HA&#xff0c;两台Mysql数据库的数据保持完全一致&#xff0c;实现方法是两台Mysql互为主从关系&#xff0c;通过keepalived配置VIP&#xff0c;实现当其中的一台Mysql数据库宕机…

YOLOv9改进策略 | 图像去雾 | 利用图像去雾网络UnfogNet辅助YOLOv9进行图像去雾检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是利用UnfogNet超轻量化图像去雾网络,我将该网络结合YOLOv9针对图像进行去雾检测(也适用于一些模糊场景),我将该网络结构和YOLOv9的网络进行结合同时该网络的结构的参数量非常的小,我们将其添加到模型里增加的计算量和参数量基本可…

2000 年至 2015 年中国(即水稻、小麦和玉米1km 网格)三种主要作物年收获面积的时空变化

摘要 可靠、连续的主要作物收获面积信息对于研究地表动态和制定影响农业生产、土地利用和可持续发展的政策至关重要。然而&#xff0c;中国目前还没有高分辨率的空间明确和时间连续的作物收获面积信息。全国范围内主要农作物收获面积的时空格局也鲜有研究。在本研究中&#xf…

家政服务|基于SprinBoot+vue的家政服务管理平台(源码+数据库+文档)

家政服务管理平台 目录 基于SprinBootvue的家政服务管理平台 一、前言 二、系统设计 三、系统功能设计 1前台模块设计 2后台功能模块 5.2.1管理员功能模块 5.2.2用户功能模块 5.2.3服务人员功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕…

Linux:进程地址空间、进程控制(一.进程创建、进程终止、进程等待)

上次介绍了环境变量&#xff1a;Linux&#xff1a;进程概念&#xff08;四.main函数的参数、环境变量及其相关操作&#xff09; 文章目录 1.程序地址空间知识点总结上述空间排布结构是在内存吗&#xff1f;&#xff08;进程地址空间引入&#xff09; 2.进程地址空间明确几个点进…

Java 对接百度网盘

文章目录 前言一、创建百度网盘账号二、代码实现1. 常量类2. 工具类3. 授权码模式授权4. 文件分片上传&#xff08;可获取进度&#xff09;--方法一5. 文件下载(可获取进度)--方法一6. 获取文件列表7. 文件分片上传&#xff08;不可获取进度&#xff09;--方法二7. 文件下载&am…

[数据集][目标检测]手枪机枪刀检测数据集VOC+YOLO格式5990张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;5990 标注数量(xml文件个数)&#xff1a;5990 标注数量(txt文件个数)&#xff1a;5990 标注…

健身房会员管理系统服务预约小程序的作用是什么

拥有完美身材/减肥/锻炼等前往健身房是个不错的选择&#xff0c;商家生意开展需要吸引同城客户并转化&#xff0c;客户也有自己的判断需要找到更全面的场地&#xff1b;完善客户消费流程利于品牌发展和不断获客转化。 运用【雨科】平台搭建健身房管理系统小程序&#xff0c;多…

SpringBoot【1】集成 Druid

SpringBoot 集成 Druid 前言创建项目修改 pom.xml 文件添加配置文件开发 java 代码启动类 - DruidApplication配置文件-propertiesDruidConfigPropertyDruidMonitorProperty 配置文件-configDruidConfig 控制层DruidController 运行验证Druid 的监控应用程序 前言 JDK版本&…

html5网页-浏览器中实现高德地图定位功能

介绍 HTML5是当前Web开发中最常用的技术之一&#xff0c;而地图应用又是其中一个非常常见的需求。高德地图是国内最受欢迎的地图服务提供商之一&#xff0c;他们提供了一系列的API&#xff0c;方便开发者在自己的网站或应用中集成地图功能。 接下来我们如何使用HTML5浏览器和高…

Unity开发——XLua热更新之Hotfix配置(包含xlua获取与导入)

一、Git上获取xlua 最新的xlua包&#xff0c;下载地址链接&#xff1a;https://github.com/Tencent/xLua 二、Unity添加xlua 解压xlua压缩包后&#xff0c;将xlua里的Assets里的文件直接复制进Unity的Assets文件夹下。 成功导入后&#xff0c;unity工具栏会出现xlua选项。 …

【C++提高编程-04】----C++之Vector容器实战

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

初步认识栈和队列

Hello&#xff0c;everyone&#xff0c;今天小编讲解栈和队列的知识&#xff01;&#xff01;&#xff01; 1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶&…

Mysql 找出未提交事务的SQL及死锁

未提交事务&#xff1a; 通过查看information_schema.INNODB_TRX视图,您可以了解当前系统中正在运行的事务情况,从而进行问题排查和性能优化。 SELECT * FROM information_schema.innodb_trx; 通过trx_state为RUNNIG,trx_started判断是否有一直RUNNING的事务。 如果有未提交…

Linux修炼之路之冯系结构,操作系统

目录 一&#xff1a;冯诺依曼体系结构 1.五大组件 2.存储器存在的意义 3.几个问题 二&#xff1a;操作系统 接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗-----------林辞忧 一&#xff1a;冯诺依曼体系结构 我们当代的计算机的基本构成都是由冯诺依曼…

【深度学习】第1章

概论: 机器学习是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析,其基础主要是归纳和统计。 深度学习是一种实现机器学习的技术,是机器学习重要的分支。其源于人工神经网络的研究。深度学习的模型结构是一种含多隐层的神经…

MySQL增删查改进阶

数据库约束表的关系增删查改 目录 一.数据库约束类型 NOT NULL约束类型 UNIQUE 唯一约束 DEFAULT 默认值约束 PRIMARY KEY&#xff1a;主键约束 FOREIGN KEY :W外键约束 二&#xff0c;查询 count&#xff08;&#xff09;两种用法 sum&#xff0c;avg&#xff0c;max…