QFuture 类可以用来获取异步计算的结果(类似 std::future ),一般配合 Qt Concurrent 模块和 QFutureWatcher 类工作。在 Qt Creator 中搜索 concurrent 可以看到一些相关示例。官方示例中, QFuture 一般和 QFutureWatcher 配合,因为 QFuture 不是 QObject 子类,没有信号槽。但是 QFuture 相关的接口会触发 QFutureCallOutEvent 事件,QFutureWatcher 接收该事件后发送对应信号。
相关类的对应基本介绍:
- QFuture:表示异步计算的结果
- QFutureWatcher:QFuture本身不带信号槽,可使用QFutureWatcher进行监控
- QFutureInterface:该类没有提供文档,出现于Qt源码。QFuture与QFutureInterface的关系类似std::future与std::promise(Qt6中基于QFutureInterface封装了一个QPromise类)。QFutureInterface可用于生成QFuture,在Qt类实现中,QFuture持有一个QFutureInterface成员。
从目前的文档和示例来看,QFuture 主要是由 Qt Concurrent 的相关接口生成,一般操作如下:
//concurrent生成future
QFuture future = QtConcurrent::run([this]{ /**/ });
//future设置给watcher进行监控
QFutureWatcher theWatcher;
theWatcher.setFuture(future);
//future对应的操作结束,触发watcher信号
connect(&theWatcher,&QFutureWatcher::finished,this,[this]{ /**/ });
本文的需求是实现一个展示多线程处理进度的进度条,但 QFuture 只有获取状态值的接口,而没有设置状态值的接口,这些都被封装在了 QFutureInterface 中。要实现需求,需要创建一个 QFutureInterface 对象,并用他来生成一个相关联的 QFuture 对象,再设置给 QFutureWatcher 进行监测,在线程中我们操作 QFutureInterface 实例就能触发 QFutureWatcher 对应的信号。
功能实现实现效果(GIF):
完整代码链接(GitHub):MyTestCode/Qt/TestQt_20200625_QFuture at master · gongjianbo/MyTestCode · GitHub
主要实现代码(组件是在 ui 上拖的):
(其实这里遇到一个问题,就是调用 cancel 来取消的话,会异常结束或者卡死,所以暂时用的 pause 来结束,线程中判断是否 pause。还要注意一个问题是,pause 或者 cancel 后,后续的设置是不会触发信号的,所以我在线程中结束了pause。)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
//QFuture类表示异步计算的结果
#include
//QFuture本身不带信号槽,可使用QFutureWatcher进行监控
#include
//QFutureInterface没有提供文档,出现于Qt源码
//QFuture与QFutureInterface的关系类似std::future与std::promise
//QFutureInterface可用于生成QFuture
//在Qt类实现中,QFuture持有一个QFutureInterface成员
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
//QFuture本身不带信号槽,可使用QFutureWatcher进行监控
QFutureWatcher myWatcher;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->btnStart,&QPushButton::clicked,[this](){
qDebug()
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?