Qt线程之QtConCurrent

在使用Qt创建线程的时候突发奇想,竟然想把UI显示放到子线程中去,然后让主线程去处理业务逻辑,说干就干,于是qt就报出了以下错误来告诉我这样做不可以:

ASSERT failure in QWidget: "Widgets must be created in the GUI thread.", file kernel\qwidget.cpp, line 1145

目前我在项目中使用线程的场景:

1.线程生命周期和主进程生命周期相同,协同主进程去处理一些业务。

2.线程生命周期只在处理某个业务时用,其它时候不调用。

 

关于第一种创建线程的方式就不多说了,可以继承QThread,如果是在linux下也可以直接使用 pthread_create等。这里只简单说下qt的高级线程接口:QtConCurrent。

在QT5中,该API从core中移除,如果要引用该API需要在xxxx.pro文件中加入:

QT += concurrent

提到QtConcurrent就不得不说QFuture,关于QFuture官方文档是这样说的:

QFuture allows threads to be synchronized against one or more results which will be ready at a later point in time. The result can be of any type that has a default constructor and a copy constructor. If a result is not available at the time of calling the result(), resultAt(), or results() functions, QFuture will wait until the result becomes available. You can use the isResultReadyAt() function to determine if a result is ready or not. For QFuture objects that report more than one result, the resultCount() function returns the number of continuous results. This means that it is always safe to iterate through the results from 0 to resultCount().

大概就是:“QFuture允许线程对一个或多个结果进行同步”,了解到这里就差不多了,我们就使用它来做线程同步。

此处我使用它主要是后台要处理业务,而UI需要进行提示,当业务处理完毕时,要结束提示,返回主界面。如下图:

此处我对QFuture进行了简单的封装:

void WaitForUISync(const QFuture<void>& future)
{
    QEventLoop loop;
    QFutureWatcher<void> watcher;
    QObject::connect(&watcher,SIGNAL(finished()),&loop,SLOT(quit()));
    watcher.setFuture(future);
    loop.exec();
    return;
}

调用方式如下:

void run_thread_test(int &ret)
{
    for (int i=0; i < 50 ; i++) {
        DEBUG<<"current thread:"<<QThread::currentThread();
        QThread::usleep(1000 * 100);

    }
    ret = 0;

}

//如果是普通函数调用方式如下:
{
    int result = -1;
    QFuture<void> featrue =QtConcurrent::run(run_thread_test,&result );
    WaitForUISync(featrue);

}


void Widget::runThreadTest(int &ret)
{
    for (int i=0; i < 50 ; i++) {
        DEBUG<<"current thread:"<<QThread::currentThread();
        QThread::usleep(1000 * 100);

    }
    ret = 0;

}

//如果是类的成员函数,调用方式如下:
{
    int result = -1;
    QFuture<void> featrue =QtConcurrent::run(this , &Widget::runThreadTest,&result );
    WaitForUISync(featrue);
}

比较好的博客:https://www.cnblogs.com/lifexy/p/10907901.html

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liu-Eleven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值