// 子线程的实现代码 #include "ctestthread.h" #include <QDebug> #include <QEventLoop> #include <QTimer> #include <QApplication> // dlg是由主线程中传递的一个窗口对象指针,demo中省去了安全检查的代码 CTestThread::CTestThread(QWidget *dlg, QObject *parent): QThread(parent), mdlg(dlg) { qDebug() << __func__ << "[Thread ID]" << QThread::currentThreadId(); } void CTestThread::run() { qDebug() << __func__ << "[Thread ID]" << QThread::currentThreadId(); // 直接在子线程里面创建一个窗口,将其移动到运用程序主线程然后开启事件循环,也是可以显示 QEventLoop eventLoop; mdlg->moveToThread(qApp->thread()); // 移动到运用程序主线程(即GUI线程) connect(mdlg, &QWidget::destroyed, &eventLoop, &QEventLoop::quit); // 窗口销毁时自动退出事件循环 QTimer::singleShot(0, mdlg, [this]() { this->mdlg->show(); }); eventLoop.exec(); // 启动事件循环,在事件循环退出前,下面的代码不会执行 qDebug() << __func__ << "Finished!"; }
// 主线程中使用 #include "mainwindow.h" #include "ui_mainwindow.h" #include "form.h" #include "ctestthread.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_btnTest_clicked() { // 创建传递给子线程的窗口 Form* dlg = new Form();// 就是一个普通的继承QWidget的窗口类 dlg->setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭时,自动delete // 创建子线程 CTestThread* thd = new CTestThread(dlg); connect(thd, &CTestThread::finished, thd, &CTestThread::deleteLater); // 线程结束时自动delete thd->start();// 启动线程 }
实现的效果:(点击主窗口中的StartTest即可创建子线程并在线程函数中弹出窗口)
运用程序输出:
10:35:44: Starting E:ProjectsCodeQtQtHelpersuild-Test-Desktop_Qt_5_15_2_MSVC2019_64bit-DebugdebugTest.exe ... MainWindow [Thread ID] 0x848 CTestThread [Thread ID] 0x848 run [Thread ID] 0x3328 run Finished!