QT-异步编程

发布于:2025-03-09 ⋅ 阅读:(16) ⋅ 点赞:(0)

1.进度条通过线程动起来

mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QSlider>
class myThread : public QThread
{
    Q_OBJECT
public:
    myThread(QObject* parent=nullptr);
protected:
    virtual void run() override;
private:

signals:
    emit void sendMove();
};

#endif // MYTHREAD_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include "mythread.h"
#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    myThread* thread;
    QString qss;
public slots:
    void recMove();
private slots:
    void on_pushButton_clicked();
};
#endif // WIDGET_H

mythread.cpp

#include "mythread.h"

myThread::myThread(QObject* parent)
    :QThread(parent)
{


}

void myThread::run()
{
    while(1)
    {
        this->msleep(100);
        emit sendMove();
    }
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    thread = new myThread(this);
    qss ="QSlider::sub-page{background-color:blue} QSlider::groove{background-color:black} ";
    ui->horizontalSlider->setStyleSheet(qss);
    QObject::connect(thread,&myThread::sendMove,this,&Widget::recMove);//传递滑块移动
}

Widget::~Widget()
{
    thread->terminate();
    delete ui;
}


void Widget::recMove()
{
    int currentValue = ui->horizontalSlider->value();
    ui->horizontalSlider->setValue(currentValue + 1);
}


void Widget::on_pushButton_clicked()
{
    thread->start();
}

2.使用QFileDialog 或者 拖放事件 + QT文件IO + QT线程

实现一个文件复制功能,要求能够复制大小超过800mb的文件

额外要求:可以在文件拷贝的时候,追加一个进度条显示拷贝了多少文件内容

mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H
 
#include <QThread>
#include <QFile>
 
class myThread : public QThread
{
    Q_OBJECT
public:
    explicit myThread(QObject* parent = nullptr);
    void setFileInfo(const QString& path, const QString& copypath);
 
signals:
    void signCopyIng(int value);
    void signCopyEnd(bool success);
 
protected:
    void run() override;
 
private:
    QString path;   // 源文件路径
    QString copypath;  // 目标文件路径
};
 
#endif // MYTHREAD_H

mythread.cpp

#include "mythread.h"
#include <QDebug>
 
myThread::myThread(QObject *parent) : QThread(parent) {}
 
void myThread::setFileInfo(const QString& path, const QString& copypath) {
    this->path = path;
    this->copypath = copypath;
}
 
void myThread::run() {
    QFile srcFile(path);
    QFile destFile(copypath);
 
    if (!srcFile.open(QIODevice::ReadOnly)) {
        emit signCopyEnd(false);
        return;
    }
 
    if (!destFile.open(QIODevice::WriteOnly)) {
        srcFile.close();
        emit signCopyEnd(false);
        return;
    }
 
    const qint64 totalSize = srcFile.size();
    qint64 copiedSize = 0;
    const int bufferSize = 1024 * 1024;
 
    while (!srcFile.atEnd()) {
        if (isInterruptionRequested()) break;
 
        QByteArray buffer = srcFile.read(bufferSize);
        qint64 writeSize = destFile.write(buffer);
 
        if (writeSize != buffer.size()) {
            break;
        }
 
        copiedSize += writeSize;
        int value = static_cast<int>(copiedSize * 100 / totalSize);
        emit signCopyIng(value);
    }
 
    srcFile.close();
    destFile.close();
 
    bool success = (copiedSize == totalSize);
    emit signCopyEnd(success);
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include "mythread.h"
#include <QTimer>
 
 
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 
private:
    Ui::Widget *ui;
    myThread* thread;
 
 
 
private slots:
    void onCopyIng(int value);
    void onCopyEnd(bool success);
 
    void on_pushButton_clicked();
};
 
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QMessageBox>
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    , thread(new myThread(this))
{
    ui->setupUi(this);
 
 
    QString qss ="QSlider::sub-page{background-color:blue} QSlider::groove{background-color:black} ";
      
 
    ui->horizontalSlider->setEnabled(false); // 禁用进度条交互
    ui->horizontalSlider->setStyleSheet(qss);
 
    ui->horizontalSlider->setRange(0, 100);
    ui->horizontalSlider->setValue(0);
    ui->label->setText("就绪");
 
    connect(thread, &myThread::signCopyIng, this, &Widget::onCopyIng);
    connect(thread, &myThread::signCopyEnd, this, &Widget::onCopyEnd);
}
 
Widget::~Widget()
{
    if (thread->isRunning()) {
        thread->requestInterruption();
        thread->wait();
    }
    delete ui;
}
 
void Widget::on_pushButton_clicked()
{
    QString path = QFileDialog::getOpenFileName(this, "选择源文件");
    if (path.isEmpty()) return;
 
    QString copypath = QFileDialog::getSaveFileName(this, "保存文件");
    if (copypath.isEmpty()) return;
 
    ui->horizontalSlider->setValue(0);
    ui->label->setText("复制中...0%");
    ui->pushButton->setEnabled(false);
 
    thread->setFileInfo(path, copypath);
 
    thread->start();
}
 
void Widget::onCopyIng(int value)
{
    ui->horizontalSlider->setValue(value);
    ui->label->setText(QString("复制中...%1%").arg(value));
}
 
void Widget::onCopyEnd(bool success)
{
    ui->pushButton->setEnabled(true);
    if (success) {
        QMessageBox::information(this, "完成", "文件复制成功!");
        ui->label->setText("复制完成");
    } else {
        QMessageBox::critical(this, "错误", "文件复制失败!");
        ui->label->setText("复制失败");
    }
    ui->horizontalSlider->setValue(0);
}


网站公告

今日签到

点亮在社区的每一天
去签到