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

本文主要是介绍qt-C++笔记之使用QtConcurrent异步地执行槽函数中的内容,使其不阻塞主界面,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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 表达式,该表达式异步执行 heavyFunctionQObject::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_OBJECTpublic: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_OBJECTpublic: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 concurrentgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsSOURCES += main.cppHEADERS +=

这篇关于qt-C++笔记之使用QtConcurrent异步地执行槽函数中的内容,使其不阻塞主界面的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1004986

相关文章

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

nginx启动命令和默认配置文件的使用

《nginx启动命令和默认配置文件的使用》:本文主要介绍nginx启动命令和默认配置文件的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录常见命令nginx.conf配置文件location匹配规则图片服务器总结常见命令# 默认配置文件启动./nginx

在Windows上使用qemu安装ubuntu24.04服务器的详细指南

《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安