这段代码是一个简单的 Qt 程序,用于演示如何在一个线程中更新 UI 控件,学习大佬的文章并做出了小修改分享在这里,借鉴文章https://blog.csdn.net/qq_14945437/article/details/98868606?spm=1001.2014.3001.5506。
总体来说,这段代码演示了如何在 Qt 中使用线程来执行后台任务,并通过信号和槽机制更新 UI 界面,同时确保线程在窗口关闭时能够正确停止和释放资源。有助于对刚接触QThread的学习。
线程实现类
#ifndef TEXTTHREAD_H
#define TEXTTHREAD_H
#include <QThread>
#include <QObject>
class textThread : public QThread
{
Q_OBJECT
public:
explicit textThread(QObject *parent = nullptr);
~textThread();
private:
// 重写run函数实现线程
void run() ;
signals:
// 加载信号
void showProgress(int progress);
};
#endif // TEXTTHREAD_H
#include "textthread.h"
#include <QDebug>
textThread::textThread(QObject *parent)
: QThread(parent)
{
}
textThread::~textThread()
{
qDebug() << "内存释放";
}
void textThread::run()
{
for (int i = 0; i<=30; ++i)
{
QThread::msleep(100);
showProgress(i);
}
}
主程序窗口类实现
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QLabel>
#include <QCloseEvent>
#include "textthread.h"
class widget : public QWidget
{
public:
widget(QWidget* ptr = nullptr);
public:
void ProgressLabelShow(int prog);
// 关闭窗口自动停止线程
void closeEvent(QCloseEvent* ev);
void deleteThread();
private:
QLabel* _edit = nullptr;
textThread* thread = nullptr;
};
#endif // WIDGET_H
#include "widget.h"
#include <QHBoxLayout>
#include <QThread>
#include <QDebug>
widget::widget(QWidget* ptr)
: QWidget(ptr)
{
// 界面
_edit = new QLabel;
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(_edit);
this->setFixedSize(100,100);
this->setLayout(layout);
thread = new textThread(this);
// 通过线程中发出信号通知Qt处理线程,并在Qt操作线程中操作控件
connect(thread, &textThread::showProgress, this, &widget::ProgressLabelShow);
// 第一种通过将finished()函数绑定到QObjec的deleteLater函数实现线程结束后自动释放内存
// 注意:使用后内存释放后会出现崩溃的现象(线程已经被释放,但存在未知信号) 希望有大佬指点一下
//connect(thread, &QThread::finished, this, &QObject::deleteLater);
//自动释放内存(第二种方法实现自动释放内存)
connect(thread, &QThread::finished, this, &widget::deleteThread);
thread->start();
}
void widget::ProgressLabelShow(int prog)
{
_edit->setText(QString::number(prog) + "%");
}
void widget::closeEvent(QCloseEvent *ev)
{
Q_UNUSED(ev)
qDebug() << "窗口关闭";
//查找当前窗口部件中是否存在名为 textThread 类型的子部件
textThread* thread = this->findChild<textThread*>();
if (nullptr == thread)
{
return;
}
if (thread->isRunning())
{
// 停止线程
thread->quit();
// 阻塞线程,等待线程结束
thread->wait();
}
}
void widget::deleteThread()
{
qDebug() << "Deleting thread...";
// 释放线程内存
thread->deleteLater();
this->close();
}
运行:
结果: