Qt开启C++线程里并访问界面

一、前言

众所周知,只要涉及界面开发,都有一句话:禁止在子线程里增删改查界面

也就是所谓的:主线程更改界面,子线程做运算

有时候发现线程不能改变界面是非常不方便的,而上面的两句话也只是“原则上”,也就是说其实是可以的。

至于有后果:【个人推测】

APP在主线程中有自己的一套消息循环,如界面绘制、重绘、更新等,如果程序员在子线程中加上这些操作,可能会产生冲突,到时候软件意外崩溃,几乎是找不到原因的啊!!!

所以本文的投机取巧要慎用,反正我不管冲了!!  

 

 

二、举例

我做过MFC、C#、Python、Matlab【不提供线程】,几乎都是这个原则,今天把这个原则深入研究一下。

三、Qt线程概述

Qt库提供线程一般有两种,加上C++自己的线程,就是三种。分别是:QThread子类、QObject子类+moveToThrad、std::thread+其他线程函数

前两种都是用来后台计算,我还没有用来改变过界面,往往通过信号与槽来让main线程修改界面,根据我的推测【还没试验,确实没必要,只用来做计算应该也够了】,是可以在他们依附的子线程里修改界面的,如何实现看下面。

第三种C++自己的线程开启函数,也就是通过线程对象+线程函数+入参的形式开启一个线程。

四、如何在线程里访问界面

仔细看Qt窗口项目代码

 

 

就是这个ui指针,它指向的Mainwindow对象,Qt内部自己将ui指针指向了自己的mainwindow.ui界面文件,所以总结来说就是:

界面也是个对象

既然界面也是个对象,那我把这个对象当做参数传递到子线程中,是可行的。

 

五、实现

1、在mainwindow.h定义线程入口函数

void getWltData(QString path);

2、mainwindow.cpp中实现并访问界面

void Mystack::getWltData(QString path)
{
    ui->label_84->setText("子线程访问界面"+path);
}

3、开启线程

void Mystack::on_pushButton_17_clicked()
{
    std::thread t(&Mystack::getWltData,this,ui->lineEdit_71->text());
    t.detach();
}

总结:

想要在子线程中访问界面,只要把界面对象传递给子线程函数即可。

注意:

线程函数要定义成类的函数,因为这样才能访问private属性的ui,如果是全局函数,则没有this指针,即使传递this进去也不能访问到private对象;

然后类函数默认有一个this入参的;

这样做有何不良反应还没发现。

 

posted @ 2020-03-19 11:20  朱小勇  阅读(1912)  评论(0编辑  收藏  举报