本文以 Qt 中的 QtConcurrent::run() 函数为例,介绍如何将函数运行在单独的线程中。

1  QtConcurrent::run()

QtConcurrent 是命名空间 (namespace),它提供了高层次的函数接口 (APIs),使所写程序,可根据计算机的 CPU 核数,自动调整运行的线程数目。

下面是 Qt 例程 runfunction,对应目录为  D:\Qt\Qt5.12.3\Examples\Qt-5.12.3\qtconcurrent\runfucntion

1.1  .pro 工程文件

使用 QtConcurrent 模块,需要在 .pro 中添加: QT += concurrent

QT += concurrent widgets
CONFIG += console SOURCES += main.cpp

1.2  main.cpp

 #include <QString>
#include <QDebug>
#include <QThread>
#include <QApplication> #include "qtconcurrentrun.h" using namespace QtConcurrent; void func(QString name)
{
qDebug() << name << "from" << QThread::currentThread();
} int main(int argc, char **argv)
{
QApplication app(argc, argv); QFuture<void> fut1 = run(func, QString("Thread 1"));
QFuture<void> fut2 = run(func, QString("Thread 2")); fut1.waitForFinished();
fut2.waitForFinished();
}

用 QtConcurrent::run() 函数,分别将  func() 运行在两个不同的线程中,输出结果如下:

"Thread 1" from QThread(0x1b74fd2ebc0, name = "Thread (pooled)")
"Thread 2" from QThread(0x1b74fd534e0, name = "Thread (pooled)")

下面是 QtConcurrent::run() 的详细使用,阅读完 2 和 3,再看上面的 runfunction 例程,就容易理解了。

2  普通函数

2.1  将函数运行在某一个线程中

extern void func();
QFuture<void> future = QtConcurrent::run(func);

如果要为其指定线程池,可以将线程池的指针作为第一个参数传递进去

extern void func();
QThreadPool pool;
QFuture<void> future = QtConcurrent::run(&pool, func);

2.2  向该函数传递参数

需要传递的参数,则跟在函数名之后,依次加入

extern void FuncWithArguments(int arg1, const QString &string);

 int integer = ...;
QString string = ...; QFuture<void> future = QtConcurrent::run(FuncWithArguments,integer,string);

2.3  获取该函数的计算结果

extern QString Func(const QByteArray &input);

QByteArray byte_array = ...;

QFuture<QString> future = QtConcurrent::run(func, byte_array);
...
QString result = future.result();

3  成员函数

将类中的成员函数运行在某一个线程中,可将指向该类实例的 引用或指针 作为 QtConcurrent::run 的第一个参数传递进去,

常量成员函数一般传递 常量引用 (const reference),而非常量成员函数一般传递 指针 (pointer)

3.1  常量成员函数

在一个单独的线程中,调用 QByteArray 的常量成员函数 split(),传递给 run() 函数的参数是 bytearray

  QByteArray bytearray = "hello world";
QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split, ',');
...
QList<QByteArray> result = future.result();

3.2  非常量成员函数

在一个单独的线程中,调用 QImage 的非常量成员函数 invertPixels(),传递给 run() 函数的参数是 &image

  QImage image = ...;
QFuture<void> future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba);
...
future.waitForFinished();
// At this point, the pixels in 'image' have been inverted

参考资料:

Qt Assistant | Qt 5.12 | Qt Concurrent | Concurrent Run

Qt 之 入门例程(二)的更多相关文章

  1. Qt 之 入门例程 (一)

    以 “Hello Qt” 为例,介绍如何建立一个 Qt 工程 . 1  QLabel 例程 QLabel 继承自 QFrame (继承自 QWidget),主要用来显示文本和图片. 1.1  Hell ...

  2. Qt 之 入门例程

    以 “Hello Qt” 为例,介绍如何建立一个 Qt 工程 . 1  QLabel 例程 QLabel 用来显示文本和图片,它继承自 QFrame (而 QFrame 继承自 QWidget) 1. ...

  3. QT从入门到入土(二)——对象模型(对象树)和窗口坐标体系

    摘要 我们使用的标准 C++,其设计的对象模型虽然已经提供了非常高效的 RTTI 支持,但是在某些方面还是不够灵活.比如在 GUI 编程方面,既需要高效的运行效率也需要强大的灵活性,诸如删除某窗口时可 ...

  4. PySide——Python图形化界面入门教程(二)

    PySide——Python图形化界面入门教程(二) ——交互Widget和布局容器 ——Interactive Widgets and Layout Containers 翻译自:http://py ...

  5. 第15.10节 PyQt(Python+Qt)入门学习:Qt Designer可视化设计界面组件与QWidget类相关的组件属性详解

    PyQt学习有阵子了,对章节的骨架基本考虑好了,准备本节就写组件的属性的,结果一是日常工作繁忙,经常晚上还要加班,二是Qt的组件属性很多,只能逐一学习.研究和整理,花的时间有点长,不过终于将可视化设计 ...

  6. QT从入门到入土(三)——信号和槽机制

    摘要 信号槽是 Qt 框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号 (signal).这种发出是没有目的的,类似广播 ...

  7. 无废话ExtJs 入门教程二十一[继承:Extend]

    无废话ExtJs 入门教程二十一[继承:Extend] extjs技术交流,欢迎加群(201926085) 在开发中,我们在使用视图组件时,经常要设置宽度,高度,标题等属性.而这些属性可以通过“继承” ...

  8. 无废话ExtJs 入门教程二十[数据交互:AJAX]

    无废话ExtJs 入门教程二十[数据交互:AJAX] extjs技术交流,欢迎加群(521711109) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...

  9. Bootstrap入门(二)栅格

    Bootstrap入门(二)栅格 Bootstrap入门(二)栅格 全局CSS样式--栅格 先引入本地的CSS文件(根据自己的文件夹,有不同的引入地址,我是放在一个新建的名为css的文件夹中) con ...

随机推荐

  1. [转载]或许您还不知道的八款Android开源游戏引擎

    或许您还不知道的八款Android开源游戏引擎         分类:             技术文章              2010-08-04 20:27     17430人阅读     ...

  2. Nginx的配置文件详解

    主配置文件: 查看nginx的进程可以看到nginx所使用的配置文件: 主配置一般会被用来设置一些全局的参数: 参数详解: user nobody nobody;          //设置nginx ...

  3. vmware克隆之后网卡起不来的问题

    问题: 克隆一台主机之后,改主机的网卡起不来,只有一个本地的回环地址网卡. 使用如下的命令都无效. /etc/init.d/network restart ifup eth0 原因: 这一vmware ...

  4. bootstrap file input 官方文档翻译

    file Input官方文档 中文翻译 file input 特性 1.这个插件会把简单的html文件变成一个更好用的文件选择输入控件,通过一个html的文件输入框,能兼容那些不支持jquery或js ...

  5. opencv配置(win10+VS2015+opencv3.1)

    Step 1:准备工作 a.win10 b.vs2015 c.opencv3.1[从http://opencv.org/downloads.html下载] Step 2.开始安装 a. 双击openc ...

  6. JavaEE开发之Spring中的多线程编程以及任务定时器详解

    上篇博客我们详细的聊了Spring中的事件的发送和监听,也就是常说的广播或者通知一类的东西,详情请移步于<JavaEE开发之Spring中的事件发送与监听以及使用@Profile进行环境切换&g ...

  7. 浓缩的才是精华:浅析GIF格式图片的存储和压缩

    成文迪, 在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦. GIF格式的历史 GIF(Graphics Interchange Format)原义是"图像互换 ...

  8. 浩哥解析MyBatis源码(四)——DataSource数据源模块

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6634880.html 1.回顾 上一文中解读了MyBatis中的事务模块,其实事务操作无非 ...

  9. 老李分享:Android性能优化之内存泄漏2

    这种创建Handler的方式会造成内存泄漏,由于mHandler是Handler的非静态匿名内部类的实例,所以它持有外部类Activity的引用,我们知道消息队列是在一个Looper线程中不断轮询处理 ...

  10. JavaScript基础学习(二)—JavaScript基本概念

    一.语法 1.区分大小写     JavaScript是一种弱类型的脚本语言.它区分大小写,变量名test与Test表示两个完全不同的变量.   2.标识符      所谓标识符就是变量.函数.属性的 ...