Qt界面程序通常什么情况下要使用到线程?
Qt界面程序在调用接口处理时间较长的任务时(如连接网络、复制文件等等耗时操作),界面在等待接口返回前会导致卡死。
为了不让界面卡死,可以使用一个子线程来处理耗时任务,关于QThread的线程在这里就不介绍了,本文讲的使用std::thread来快速方便解决这个问题。
(资料图片仅供参考)
解决问题思路
1、现代大部分C++编译器已经支持C++11 的自带线程类std::thread,线程随时创建,随时销毁方便。
2、QEventLoop类事件循环可用来等待线程执行完毕,并且界面不会因等待而卡死。
3、在线程任务执行结束后,可给QEventLoop对象发送一个信号,告知程序执行结束,QEventLoop对象在收到信号时退出循环,向上告知线程执行结果。
4、另外,通过
std::async([&]{ });
显得更方便些,头文件需要包含#include。
详见另一篇博文:
程序示例
ThreadTest界面类头文件如下:
/** @file ThreadTest.h* @author lesliefish* @date 2018/08/31*/#pragma once#include #include #include #include \"ui_ThreadTest.h\"class ThreadTest : public QWidget{Q_OBJECTpublic:explicit ThreadTest(QWidget *parent = Q_NULLPTR);signals:// 线程执行结束后发送此信号void signalRunOver();private:// 测试函数void test();private:Ui::ThreadTestClass ui;};
ThreadTest界面类cpp文件具体实现如下:
#include \"ThreadTest.h\"#include ThreadTest::ThreadTest(QWidget *parent): QWidget(parent){ui.setupUi(this);// 绑定信号 点击按钮后执行test函数connect(ui.pushButton, &QPushButton::clicked, [&]{test();});}/** @fn ThreadTest::test* @brief 测试函数 点击界面按钮后执行* @return void*/void ThreadTest::test(){// 假设需要知道线程的执行结果runResultbool runResult{ false };// 定义一个loop对象QEventLoop loop;// 绑定信号 在loop收到界面发送的signalRunOver信号后,退出循环connect(this, &ThreadTest::signalRunOver, &loop, &QEventLoop::quit);// 声明一个线程,处理耗时任务 传入匿名函数 在声明testThread后直接开启一个线程执行匿名函数体std::thread testThread([&]{// runResult = 连接网络 、拷贝文件、等等耗时操作 实际执行的任务放在这个位置执行// 执行耗时操作完成后 发出信号 告知线程执行结束emit signalRunOver();});// 分离线程 让其自生自灭(销毁线程)testThread.detach();// 在此处执行循环 等待线程的执行结果loop.exec();// 以上线程执行完成后执行以下代码if (!runResult){// 处理结果 整个过程界面不会卡死}}
如上,按以上操作可以保证界面在执行耗时任务时不会卡顿。
【领 QT开发教程 学习资料, 点击下方链接莬费领取↓↓ ,先码住不迷路~】
点击这里:
Copyright © 2015-2022 欧洲公司网版权所有 备案号:沪ICP备2022005074号-23 联系邮箱: 58 55 97 3@qq.com