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!

 

posted @ 2021-06-01 10:39  碎银三二两  阅读(1671)  评论(0编辑  收藏  举报