QT实现多线程模拟一个下载任务

本文介绍了如何在Qt中创建一个线程,通过信号和槽机制实现实时更新UI控件,并在窗口关闭时正确停止和释放线程资源。代码展示了如何在textThread类中执行后台任务并通过widget类中的槽函数显示进度。
摘要由CSDN通过智能技术生成

这段代码是一个简单的 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();
}

运行:

结果:

你可以使用Qt多线程机制来实现任务的暂停、恢复和终止功能。以下是一个基本的示例代码: ```cpp #include <QThread> #include <QMutex> #include <QDebug> // 自定义的工作线程类 class WorkerThread : public QThread { public: // 构造函数 WorkerThread(QObject *parent = nullptr) : QThread(parent), m_paused(false), m_terminated(false) {} // 提供外部控制线程暂停的方法 void pause() { QMutexLocker locker(&m_mutex); m_paused = true; } // 提供外部控制线程恢复的方法 void resume() { QMutexLocker locker(&m_mutex); m_paused = false; m_condition.wakeAll(); } // 提供外部控制线程终止的方法 void terminate() { QMutexLocker locker(&m_mutex); m_terminated = true; m_condition.wakeAll(); } protected: // 线程执行函数 void run() override { int count = 0; while (true) { // 检查是否被暂停或终止 QMutexLocker locker(&m_mutex); if (m_paused) { m_condition.wait(&m_mutex); // 等待恢复信号 } if (m_terminated) { break; } // 执行任务 qDebug() << "Count:" << count++; msleep(1000); // 休眠1秒 } } private: QMutex m_mutex; QWaitCondition m_condition; bool m_paused; bool m_terminated; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 创建并启动工作线程 WorkerThread workerThread; workerThread.start(); // 模拟控制任务的暂停、恢复和终止 QTimer timer; timer.setInterval(3000); // 3秒后暂停任务 QObject::connect(&timer, &QTimer::timeout, [&workerThread]() { qDebug() << "Pausing task..."; workerThread.pause(); }); timer.start(); QTimer timer2; timer2.setInterval(6000); // 6秒后恢复任务 QObject::connect(&timer2, &QTimer::timeout, [&workerThread]() { qDebug() << "Resuming task..."; workerThread.resume(); }); timer2.start(); QTimer timer3; timer3.setInterval(9000); // 9秒后终止任务 QObject::connect(&timer3, &QTimer::timeout, [&workerThread]() { qDebug() << "Terminating task..."; workerThread.terminate(); }); timer3.start(); return a.exec(); } ``` 在上面的示例中,我们创建了一个名为`WorkerThread`的自定义线程类,它继承自`QThread`。该类提供了三个方法来控制线程的暂停、恢复和终止。 在`run()`函数中,我们使用一个无限循环来执行任务。在每次循环开始时,我们检查是否被暂停或终止。如果被暂停,则调用`m_condition.wait(&m_mutex)`等待恢复信号。如果被终止,则跳出循环,结束线程。 在主函数中,我们创建并启动了一个`WorkerThread`实例,并使用`QTimer`模拟控制任务的暂停、恢复和终止。通过设置不同的定时器间隔,可以调整任务执行时间。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值