QFutureWatcher & QFuture 使用

什么是QFutureWatcher?

QFutureWatcher允许使用信号与槽监控QFuture;QFutureWatcher提供了关于QFuture中通知和信息函数。通过setFuture设置关注的QFuture。

什么是QFuture?

未来的预测?

QFuture类代表着异步计算的结果。为了开始一个计算。我们需要使用Qt Concurrent框架中几个api接口中一个。

QFuture允许线程根据一个至多个当前稍后的结果进行同步,结果的类型须具有构造函数和拷贝构造函数。某一刻上调用result(),resultAt(),results()函数,对获得产生的结果,QFuture将会阻塞直到获得结果。可以调用isResultReadyAt()函数判断当前是否取得结果。对那些可以返回多个结果的,可以通过调用resultCount()函数当前连续的结果。能够从索引0到resultCount()之间迭代结果是安全的。

什么是Qt Concurrent?

QtConcurrent(并发)命名空间提供了高级api接口,使得不使用低级线程原子操作(互斥锁,信号量)编写多线程函数变得可能。通过Qtcurrent编写多线程程序自动调整线程的数量,线程的多少依赖于处理器核心数。这意味着当前的程序能够在未来多核处理器上运行。

API举例:

 QtConcurrent::map() applies a function to every item in a container, modifying the items in-place.
为每一个在容器中的item项传递到一个函数中,适当的修改item项。

QFutureWatcher介绍:

在QFutureWatcher中涉及与QFuture函数相关有:
QFutureWatcher: progressValue(), progressMinimum(), progressMaximum(), progressText(), isStarted(), isFinished(), isRunning(), isCanceled(), isPaused(), waitForFinished(), result(), and resultAt(). 

QFutureWatcher也提供槽函数:
The cancel(), setPaused(), pause(), resume(), and togglePaused()

涉及状态变化的信号函数有:
started(), finished(), canceled(), paused(), resumed(), resultReadyAt(), and resultsReadyAt();

涉及进度信息的信号有:

progressRangeChanged(), void progressValueChanged(), and progressTextChanged() 

通过调用setPendingResultLimit函数可以实现节流控制,当resultReadyAt()以及 resultsReadyAt()的信号挂起的个数超过限制时,涉及future的计算将自动的停止。
一旦挂起的信号低于了限制,将恢复运行。

例如:开始一个计算并且完成时回调一个函数。

#ifndef SSS_H
#define SSS_H
#include "QObject"
#include "QDebug"
class MyClass:public QObject
{
Q_OBJECT
public:
    void handleFinished()
    {

        for(int i =0 ;i < 10;i++)
        {
            qDebug() << "handleFinished:" << i << endl;
            const int work = 1000 * 1000 * 400;
            volatile int v = 0;
            for (int j = 0; j < work; ++j)
                ++v;

        }

    }
};
#endif // SSS_H
#include <QtWidgets>
#include <QtConcurrent>
#include "sss.h"
#include <functional>

using namespace QtConcurrent;

int finished(void)
{
    qDebug() << "finish" << endl;
    return 0;
}
int main(int argc, char **argv)
{
    QApplication app(argc, argv);


    // Instantiate the objects and connect to the finished signal.
      MyClass myObject;
      QFutureWatcher<int> watcher;
      QObject::connect(&watcher, &QFutureWatcher<int>::finished, &myObject, &MyClass::handleFinished);

      std::function<int(void)> func = finished;
      // Start the computation.
      QFuture<int> future = QtConcurrent::run(func);
      watcher.setFuture(future);


      watcher.waitForFinished();
      qDebug() << "Canceled?" << watcher.future().isCanceled();

     app.exec();

}

执行结果:

举例:

官方进度条

        Random access iterators can be faster in cases where Qt Concurrent is iterating over a large number of lightweight items, since they allow skipping to any point in the container. In addition, using random access iterators allows Qt Concurrent to provide progress information trough QFuture::progressValue() and QFutureWatcher::progressValueChanged().

适用随机访问的迭代能够允许Qtcurrent提供进度信息,可以通过Qfuture::progressValue()以及QfutureWatcher::progressValueChanged();

 

 

异步示例:
        执行一个耗时长过滤奇数字运算,通过QfutureWatch更新进度。

异步示例代码:
        

#include "QFutureWatcher"
#include "QFuture"
#include "QProgressDialog"
#include <QApplication>
#include <QtConcurrent>
using namespace QtConcurrent;
bool isEvenNumber(const int &  num)
{
    //delay
    const int work = 1000 * 1000 *10;
    volatile int v = 0;
    for (int j = 0; j < work; ++j)
        ++v;
    qDebug() << "Number:" << num;
    if(num % 2 != 0)
    {
       return false;
    }
    else
    {
       return true;
    }
}
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    int nums = 1000;
    QList<int> list;
    for(int i = 0; i<nums ;i ++)
    {
        list << i;
    }
    QProgressDialog progress_dig;
    QFutureWatcher<void> watch;

    //关联设置进度条范围
     
    QObject::connect(&watch,&QFutureWatcher<void>::progressValueChanged,&progress_dig,&QProgressDialog::setValue);   QObject::connect(&watch,&QFutureWatcher<void>::progressRangeChanged,&progress_dig,&QProgressDialog::setRange);

    std::function<bool(const int &)> func = isEvenNumber;
    QFuture<void> future = QtConcurrent::filter(list,func);
    watch.setFuture(future);

    progress_dig.exec();

    watch.waitForFinished();

    return a.exec();
}

异步执行结果:

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2022年11月4日-2022年11月14日购买当前课程赠送课程学习地址如下:https://edu.csdn.net/course/detail/32434https://edu.csdn.net/course/detail/35658https://edu.csdn.net/course/detail/30223https://edu.csdn.net/course/detail/32408https://edu.csdn.net/course/detail/32429注:因赠送课程不会出现在已订阅课程列表中,以下课程学习地址一定要收藏保存。#课程服务 在线答疑:本课程设有专门的讨论留言区,学习中遇到任何问题,直接给老师留言即可,老师都会及时进行回复。远程协助:如果遇到复杂问题,老师还可进行远程协助,这个一般可不是一两百元的课程就能享受到的。源码分享:为了让大家更好的进行项目实战,老师还将课程中涉及到的所有源码分享给学员,按照视频中的提示进行下载即可。在CSDN分享C++ Qt开发知识已经有6年了,感谢众多博友对我的支持,了解到很多人对Qt使用还是有些困扰,例如Qt环境搭建,Qt布局的使用,如何使用Qt编写复杂的界面,如何自定义非标控件,Qt如何和Web交互,Qt和后台接口如何交互等;经过这几年的整理,我决定出这套《Qt高级开发视频教程》,带领大家学习Qt高级开发知识,学习如何使用Qt开发企业级别的项目;通过本课程的学习,大家将会达到企业招聘的中高级要求。为了照顾零基础学员,本课程第一章会介绍Qt环境搭建、QtCreator / VS2019的基本使用方法,Qt整体架构、Qt信号机制,Qt内存管理等知识。即使没有Qt开发的学习经验,也能跟着课程顺利学习。课程核心知识点地图如下: 课程每章核心知识点介绍如下: 第一章:介绍Qt环境搭建、QtCreator / VS2019的基本使用方法,Qt整体架构、Qt信号机制,Qt内存管理等知识。第二章:了解到很多学员对于Qt界面布局很不熟悉,将会详细介绍Qt设计器布局,以及如何C++代码手写布局,从常见的企业级项目入手,带领大家学会各种布局的实现,例如WPS、腾讯会议、优酷、迅雷等界面的实现;界面布局会了,这是企业项目开发的第一步,还有更重要的无边框窗口,如何设计一个合理的无边框窗口很重要,第三/四章:详细介绍如何实现一个无边框窗口,如何自定义标题栏,如何实现拖拽拉伸;第四章将会介绍如何自定义非标控件,优化Qt界面。第五章:介绍Qt web混合编程,一个商用项目,必然会涉及到web交互,这也是很多Qt开发者的弱项,这一章讲详细介绍C++ Qt web混合开发。第六章:既然是做企业级项目,必然需要和后台交互,http编程也是必要的,将详细介绍http编程,用户注册,登录,后台接口请求等知识;通过第五、六章的学习,将会是你的Qt开发技术更上一层楼。第七章:介绍Qt并发编程,耗时任务处理,进程调用等知识。第八、九章:讲解 Qt 比较重要的知识,图形视图结构,以及MVD模式;通过这两章的学习,大家会对图形视图有更好的了解。第十章:本章是独立章节,主要介绍Qt中一些特殊技巧,项目编译,dpi适配、多语言等知识。第十一章:是我们的企业级项目实战:实现一个视频会议客户端,本项目可以进行多人视频通话,直播,桌面分享等功能,本项目我会从零开始,进行项目搭建,功能调试,bug fixed, 带领大家做一个企业级项目。希望通过本课程的学习,大家的C++ Qt开发技术能有质的飞越,能找到自己心仪的工作。课程中如果讲的不对的地方,请大家指出,我及时修正,我也只是一个普通开发者,也不是所有的技术都会,尽我所能,把我所会的教给大家,让我们一起为Qt的发展,尽一份绵薄之力。 下面是本课程一些项目的截图: 1 可以滑动的设置界面         2 所有图形的绘制       3 视频播放器          4 高仿youku界面         5 视频会议         相信通过本课程的学习,大家有能力实现绝大部分客户端项目,从此用C++ Qt再也不会有难写的界面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值