在QT中我们一般使用线程会创建一个继承自线程函数的线程类,然后在实现run()函数,例如:
#include <QThread>
#include <QDebug>
class WorkerThread : public QThread
{
Q_OBJECT
public:
WorkerThread(QObject *parent = nullptr) : QThread(parent) {}
protected:
void run() override {
qDebug() << "Worker thread";
sleep(1);
}
};
int main(int argc, char *argv[])
{
WorkerThread workerThread;
workerThread.start(); // 启动线程
while(1){
//阻塞
}
//也可以使用workerThread.wait() 等待线程结束,这样也可以阻塞如果你的线程中的是死循环的话
return 0;
}
就像这样,可以开启另一个线程来运行打印Worker thread。
在MainWindow类中,使用这个线程想在任务函数中调用ui就特别麻烦,官方自然会出手,在在 Qt 5.10 及更高版本中可以这样来创建一个线程,可以使用QThread::create()来直接创建一个线程,示例:
#include <QThread>
#include <QDebug>
void myFunction() {
for(int i=0;i<1000;i++){
qDebug() << "Hello from thread" << QThread::currentThread();
}
}
int main(int argc, char *argv[]) {
QThread *thread = QThread::create(myFunction);
thread->start();
thread->wait();//等待线程结束
delete thread;
return 0;
}
这样写有时候会遇到这里的局部变量无法在任务函数中使用,自然会想到lambda表达式,在这里把i作为主函数中的局部变量,如下:
#include <QThread>
#include <QDebug>
int main(int argc, char *argv[]) {
int i;
QThread *thread = QThread::create([&i](){
for(;i<1000;i++){
qDebug() << "Hello from thread" << QThread::currentThread();
}
});
thread->start();
thread->wait();//等待线程结束
delete thread;
return 0;
}
别忘记在QT 程序中使用时,线程结束后,删掉线程,连接槽对应的信号槽即可,线程结束时会自动回收,如下:
QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);
QObject::connect(thread, &QThread::finished, &app, &QCoreApplication::quit);
最后再推一个线程的创建方法,本人偏向于这个,很好用,如下:
QtConcurrent::run([this](){
QMessageBox::information(this, "提示", "线程开始运行!");
ui->label_39->setText(QString::number(12.1, 'f', 3));
ui->label_40->setText(QString::number(12.2, 'f', 3));
ui->label_41->setText(QString::number(12.3, 'f', 3));
});
最后是这个抓取this就可以使用ui指针,有点类似继承。