QT-异步编程

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

mythread.h

cpp 复制代码
#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

cpp 复制代码
#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

cpp 复制代码
#include "mythread.h"

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


}

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

widget.cpp

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

cpp 复制代码
#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

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

cpp 复制代码
#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

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);
}
相关推荐
xcyxiner2 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner3 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner3 天前
DicomViewer (添加模型类)3
qt
xcyxiner4 天前
DicomViewer (目录调整) 2
qt
xcyxiner4 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR0066 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术6 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript
码云数智-园园6 天前
C++20 Modules 模块详解
java·开发语言·spring
swordbob6 天前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
源分享6 天前
Java线程同步的多种实现方法(非常详细)
java·开发语言·jvm