// 子線程的實現代碼 #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:\ProjectsCode\Qt\QtHelpers\build-Test-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug\debug\Test.exe ... MainWindow [Thread ID] 0x848 CTestThread [Thread ID] 0x848 run [Thread ID] 0x3328 run Finished!