Qt线程常用的3种方式:QThread/QtConcurrent::run/moveTo..
一、前言
为了避免UI界面卡顿,一般长耗时的任务会通过子线程处理,处理完成后将结果发送给UI线程去显示,Qt提供了多种创建线程的方式,这篇文章介绍常用的3种。
二、QThread
第一种方式采用继承QThread,然后重写 run()的方法。这种方式存在以下的注意点:
① MyThread假如在UI线程内实例化,那么其槽函数依附的线程在UI线程,导致此槽函数实际在UI线程执行。
② run()
函数执行完毕后,线程会结束并触发QThread::finished
信号,即使重新调用start()
启动线程,线程ID也会是新的。
③ 如果在run()函数内,执行QThread::exec,开启事件循环,线程不会finished,除非手动调用quit()方法关闭线程
#include <QObject>
#include <QThread>
#include <QTimer>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = nullptr);
void run() override;
bool bFlag=false;
QTimer*timer;
signals:
void myThreadSend(QString str);
public slots:
void do_ThreadSlots();
private:
int count=0;
};
三、QtConcurrent::run
QtConcurrent提供了一种高级的API,调用线程池内的线程执行长耗时的方法。对于一些临时性的任务,使用这种方式特别方便。由于不是继承自QObject,所以无法使用信号和槽的机制。如果需要在线程执行完成后发出通过UI线程去显示,可以结合QFuture和QFutureWatcher搭配使用。
注意子线程不要直接刷新UI控件,个别情况下导致报错发生,可以使用QMetaObject::invokeMethod 的方式执行UI线程的方法。
flag=true;
QFutureWatcher<int> *watcher=new QFutureWatcher<int>();
connect(watcher,&QFutureWatcher<int>::finished,this,[watcher,this]()
{
int num=watcher->result();
QMessageBox::information(this,"提示",QString("线程结束,执行到%1").arg(num));
watcher->deleteLater();
});
QFuture<int> future= QtConcurrent::run([=](){
int ii;
for (int var = 0; var < 5000; ++var) {
ii=var;
//ui->lab_Show->setText(QString::number(var));
QMetaObject::invokeMethod(this,"on_updatelabel",Qt::ConnectionType::AutoConnection,Q_ARG(int,ii));
if(flag==false)
{
break;
}
QThread::msleep(200);
}
return ii;
});
watcher->setFuture(future);
四、QObject.moveToThread
相较于继承QThread
,这种方式更常用,因为它可以避免QThread
子类的槽函数在UI线程内执行的问题。
一般创建一个继承自QObject
的线程类,可以在该类内创建多个槽函数,外部通过信号和槽机制触发时,槽函数会在子线程中执行。
注意:
① 调用start()
启动线程后,线程不会主动结束,而是进入等待状态。只有当子类的槽函数被触发时,线程才会被唤醒并执行相应的任务。因此,可以多次触发槽函数,而且线程ID不会改变
② 在子类使用QTimer循环触发信号,执行里面的槽函数,也是在子线程内进行的
class ClassmoveTo:public QObject
{
Q_OBJECT
public:
ClassmoveTo();
~ClassmoveTo();
bool flag=false;
int count;
QTimer *timer;
public slots:
void doWork();
void doWork1();
signals:
void sendNum(int num);
void sendStr(QString str);
};
原文地址:https://blog.csdn.net/qq_42537006/article/details/143952506
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!