QT-子线程访问主界面UI控件的有效方法

引言

        当软件需要导入大量数据文本时,若显示控件操作放在主界面UI线程中,会导致在导入数据的过程中存在界面卡死的现象,这种现象在工业控制工况中中是致命的。因此本文章旨在实现非UI子线程对UI主线程的操作。

        这里举一个简单的Demo,大文本数据通过子线程实现在主线程QTextedit文本框中显示,确保主界面不卡死正常运行。

操作

       1、新建一个自定义类,该类继承与QThread,此外使用Q_OBJECT 宏声明,中头文件引入#include <QObject>、#include <QThread>否则moc报错,打不开你信定义的类CPP文件。

        2、(.h)文件中,声明run()函数,并建立自定义信号void startDisplaySignal(QString b);

#pragma once
#include <QObject>
#include <QDebug>
#include<fstream>
#include<sstream>
#include<vector>
#include "../DllModule_KRMotion/IEC_ShareMem.h"
#include "LookAheadPara.h"
#include <QThread>
using namespace std;
class getPointCoordinate : public QThread
{
    Q_OBJECT
public:
    getPointCoordinate();
    ~getPointCoordinate();

public:
    //类的变量声明
    string vFileAddress;                                 //文件地址
    vector<strPointCoordinate> vPointCoordinateVector;   //点的坐标数组
    vector<strPointCoordinate> vPointCoordinateVector2;   //点的坐标数组
    
    int vPointNumber;                                    //点的数量
    
    //所有点的坐标极值
    double xMax;
    double xMin;
    double yMax;
    double yMin;
    double zMax;
    double zMin;

    int aa;

public:
    //类的函数声明
    //获取点的坐标向量
    void fGetPointCoordinateVector();
    void fGetPointCoordinateMax();
    void fGetPointCoordinateMin();
protected:
    void run();
signals:
    void startDisplaySignal(QString b);
    void stoop();
    void starttt();
};

3、(.cpp)文件

void getPointCoordinate::run()
{

    for (aa; aa <vPointCoordinateVector.size(); aa++)
    {
        QString sstringNum = QString::number(aa + 1, 10, 0);
        int numLen = sstringNum.length();
        for (; numLen < 3; numLen++)
        {
            sstringNum = " " + sstringNum;
        }
        QString sGCoor = QString::number(vPointCoordinateVector[aa].gCoordinate, 10, 0);
        int gCoorLen = sGCoor.length();
        for (; gCoorLen < 8; gCoorLen++)
        {
            sGCoor = " " + sGCoor;
        }
        QString sXCoor = QString::number(vPointCoordinateVector[aa].xCoordinate, 10, 3);
        int xCoorLen = sXCoor.length();
        for (; xCoorLen < 8; xCoorLen++)
        {
            sXCoor = " " + sXCoor;
        }
        QString sYCoor = QString::number(vPointCoordinateVector[aa].yCoordinate, 10, 3);
        int yCoorLen = sYCoor.length();
        for (; yCoorLen < 8; yCoorLen++)
        {
            sYCoor = " " + sYCoor;
        }
        QString sZCoor = QString::number(vPointCoordinateVector[aa].zCoordinate, 10, 3);
        int zCoorLen = sZCoor.length();
        for (; zCoorLen < 8; zCoorLen++)
        {
            sZCoor = " " + sZCoor;
        }
        QString strTol;
        strTol = "[" + sGCoor + sXCoor + sYCoor + sZCoor + "]";
        //ui.textEditG->append(strTol);
        emit startDisplaySignal(strTol);
        qDebug() << "ryh1:" << QThread::currentThreadId();
        //_sleep(50);
    }

    qDebug() << "ryh2:" << QThread::currentThreadId();
    emit stoop();
}

4、Widget主界面

        在(.h)文件中声明自定义类的对象:getPointCoordinate    *pointCoordinateVector;

并在(.cpp)文件的构造函数中建立连接:

pointCoordinateVector = new getPointCoordinate();

connect(pointCoordinateVector, SIGNAL(startDisplaySignal(QString)), ui.textEditG, SLOT(append(QString)), Qt::QueuedConnection);  

5、写导入文件的操作,并在文件导入完成后触发子线程开启

void WorkstationHMI::on_openGCodeFileBtn_clicked()
{
    //打开文件夹中轮廓文件
    QString OpenFileG, OpenFilePathG;
    OpenFileG = QFileDialog::getOpenFileName(this,
        "打开存储点坐标的文件",
        "",
        "(*.txt);;All(*.*)");
    if (OpenFileG != "")
    {
        //显示文件的路径
        OpenFileInfoG = QFileInfo(OpenFileG);
        OpenFilePathG = OpenFileInfoG.filePath();
        ui.GCodeFilePath->setText(OpenFilePathG);
    }
    else QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("文件为空,请重新选择!"));
    pointCoordinateVector->vFileAddress = OpenFileG.toStdString();     //将存储点坐标的文件的地址给点坐标数组类的对象  
    pointCoordinateVector->vPointCoordinateVector.clear();
    
    pointCoordinateVector->fGetPointCoordinateVector();   //调用数据提取函数,将数据保存在容器中
    ui.textEditG->clear();                      //先清空文本框中的内容
    pointCoordinateVector->aa = 0;      //优雅退出子线程
    pointCoordinateVector->start();

如下图,点击打开文件即可执行上述操作,确保了主界面不卡顿。
}

 感谢收看,评论沟通。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DaSheng Ren

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值