引言
当软件需要导入大量数据文本时,若显示控件操作放在主界面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();如下图,点击打开文件即可执行上述操作,确保了主界面不卡顿。
}感谢收看,评论沟通。