> 文档中心 > QT之处理密集响应时的保持(界面操作无反应)

QT之处理密集响应时的保持(界面操作无反应)

前因:如果处理一个特定任务上耗费的时间过多时,那么用户界面就会变得无法响应。
解决方案:
重点:多线程

一. 使用processEvents()函数来保持用户界面的响应-----在代码中频繁调用该函数即可QApplication::processEvents()。这个函数告诉QT处理所有那些还没有被处理的各类事件,然后将控制权返回给调用者。

使用这个方法的时候存在一个潜在的问题应用程序还在执行的时候,就关闭了主窗口或者点击了其他响应,会产生预料不到的后果解决方案:替换成QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);

二. 使用多线程
方式一:继承QThread重写虚函数run().
在这里插入图片描述
示例:
.h
在这里插入图片描述
.cpp run函数里面放自己需要耗时的操作
在这里插入图片描述
调用,如此便开启了一个线程

SendMsgThread *smt = new SendMsgThread();    smt->start();

注:如果需要删除一个存在于不同线程中的QObject对象,则必须调用线程安全的**QOBject::deleteLater()**函数,它可以置入一个延期删除时间.

方式二:void QObject::moveToThread ( QThread * targetThread )子类化QObject,利用信号和槽进行关联
1.定义一个继承QObject的类A;
2.在类A里定义一个槽函数slot();
3.QThread *thread = new QThread();将类A的实例的对象a调用moveToThread(thread);
4.绑定信号槽connect(thread, &QThread::started, a,&A::slot());//绑定线程的开始信号,线程开始后就会执行类A的槽函数
5.启动线程thread.start()。
具体使用方法以及如何利用moveToThread创建多线程的方法可以看这篇博客
QT 多线程 之MoveToThread使用详解

方式三:并发模块:QtConCurrent::run()
QtConcurrent这是一个高级 API,构建于QThreadPool之上,它提供更高层次的函数接口(APIs),使所写的程序,可根据计算机的CPU核数,自动调整运行的线程数量.
主要功能是令启动一个线程来执行一个函数.
注意,QtConcurrent是一个命名空间而不是一个类,因此其中的所有函数都是命名空间内的全局函数。
使用时要添加:
pro文件:QT += concurrent
头文件:
QT之处理密集响应时的保持(界面操作无反应)

使用方法:
QtConcurrent::run()可以开辟一个单独的线程来运行我们定义的函数(可以在里面执行一些耗时或者需要并行的计算),QtConcurrent::run()返回一个QFuture模板类,用来处理函数的返回值。
QFuture future;//可以获得计算的结果值
future.waitForFinished();等待线程结束,实现阻塞。
future. isFinished() 判断线程是否结束
future.isRunning() 判断线程是否在运行
future.result() 取出线程函数的返回值
1 全局函数或静态函 ,作为线程函数------------线程执行不带参数
QFuture QtConcurrent::run(Function function, …),例:
QT之处理密集响应时的保持(界面操作无反应)
QT之处理密集响应时的保持(界面操作无反应)

2 线程执行类成员函数(带参数):run的第一个参数必须是const引用或者对象指针
QT之处理密集响应时的保持(界面操作无反应)
3 结构体函数作为线程函数
sturct worker
{
int ID;
void worker::threadFunc()
{ }
};
worker work;
QtConcurrent::run(&work,&worker::threadFunc);

使用示例:
在这里插入图片描述

QT之处理密集响应时的保持(界面操作无反应) 新人创作打卡挑战赛 QT之处理密集响应时的保持(界面操作无反应) 发博客就能抽奖!定制产品红包拿不停!