Qt子線程中顯示窗口部件的一個方法


// 子線程的實現代碼
#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!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM