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
    评论
使用QtConcurrent和QFile来实现线程读取文件,可以通过以下步骤实现: 1. 引入头文件 ```cpp #include <QtConcurrent/QtConcurrent> #include <QFile> ``` 2. 定义任务函数 ```cpp void readFile(const QString& filePath) { QFile file(filePath); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QString data = QString::fromUtf8(file.readAll()); file.close(); emit readFinished(data); } } ``` 3. 在主线程中调用QtConcurrent::run()函数,该函数会在后台线程中执行任务函数,并返回一个QFuture对象,用于检查任务执行状态。 ```cpp QString filePath = "file.txt"; QFuture<void> future = QtConcurrent::run(readFile, filePath); ``` 4. 在主线程中连接任务函数的信号readFinished()到槽函数,用于处理读取到的数据。 ```cpp connect(this, &MainWindow::readFinished, this, &MainWindow::onReadFinished); ``` 5. 在任务函数中定义一个信号readFinished(),用于向主线程发送读取到的数据。 ```cpp signals: void readFinished(QString data); ``` 6. 在槽函数中处理读取到的数据,例如显示在文本框中。 ```cpp void MainWindow::onReadFinished(QString data) { ui->textEdit->setText(data); } ``` 需要注意的是,由于文件读取可能会比较耗时,因此我们需要确保在任务执行期间 UI 线程不会被阻塞,否则应用程序会出现假死现象。为了避免这种情况,建议将文件读取任务放在一个单独的线程中执行,而不是在 UI 线程中执行。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Liu-Eleven

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

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

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

打赏作者

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

抵扣说明:

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

余额充值