qt作业day5

1:是进度条通过线程自己动起来

头文件 (mythread.h)

cpp 复制代码
#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QSlider>

class mythread : public QThread {
    Q_OBJECT

public:
    explicit mythread(QSlider* slider, QObject* parent = nullptr);
    void stop(); // 停止线程

protected:
    void run() override;

private:
    QSlider* slider; // 需要控制的滑块
    bool stopped;    // 线程停止标志
};

#endif // MYTHREAD_H

2. 实现文件 (mythread.cpp)

cpp 复制代码
#include "mythread.h"
#include <QThread>

mythread::mythread(QSlider* slider, QObject* parent)
    : QThread(parent), slider(slider), stopped(false) {
    // 初始化
}

void mythread::stop() {
    stopped = true; // 设置停止标志
}

void mythread::run() {
    while (!stopped) {
        int value = slider->value();
        int maximum = slider->maximum();

        if (value < maximum) {
            slider->setValue(value + 1); // 增加滑块的值
        } else {
            break; // 如果滑块达到最大值,退出循环
        }

        QThread::msleep(100); // 休眠 100 毫秒
    }
}

头文件 (widget.h)

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSlider>
#include <QPushButton>
#include "mythread.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget {
    Q_OBJECT

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

private slots:
    void on_ok_button_clicked();
    void onSliderReleased();

private:
    Ui::Widget* ui;
    mythread* sliderThread; // 滑块自动滑动线程
};

#endif // WIDGET_H

实现文件 (widget.cpp)

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QInputDialog>

Widget::Widget(QWidget* parent)
    : QWidget(parent), ui(new Ui::Widget) {
    ui->setupUi(this);

    // 设置滑块的样式
    ui->horizontalSlider->setStyleSheet(R"(
        QSlider::groove:horizontal {
            background: #CCCCCC; /* 没有滑过的部分(右侧)为灰色 */
            height: 10px;
            border-radius: 5px;
        }

        QSlider::sub-page:horizontal {
            background: #0078D7; /* 滑过的部分(左侧)为蓝色 */
            height: 10px;
            border-radius: 5px;
        }

        QSlider::handle:horizontal {
            background: #FFFFFF; /* 滑块的背景颜色 */
            width: 20px;
            height: 20px;
            margin: -5px 0; /* 调整滑块的位置 */
            border-radius: 10px;
            border: 2px solid #000000; /* 滑块的边框 */
        }
    )");

    // 创建滑块自动滑动线程
    sliderThread = new mythread(ui->horizontalSlider, this);

    // 连接滑块的释放信号到槽函数
    connect(ui->horizontalSlider, &QSlider::sliderReleased, this, &Widget::onSliderReleased);

    // 启动线程
    sliderThread->start();
}

Widget::~Widget() {
    delete ui;
}

void Widget::on_ok_button_clicked() {
    // 示例:打开输入对话框
    QInputDialog::getText(this, "请输入", "请输入");
}

void Widget::onSliderReleased() {
    // 停止线程
    sliderThread->stop();
    sliderThread->quit();
    sliderThread->wait();
}

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

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

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

1. 头文件 (filecopier.h)

cpp 复制代码
#ifndef FILECOPIER_H
#define FILECOPIER_H

#include <QThread>
#include <QFile>

class FileCopier : public QThread {
    Q_OBJECT

public:
    FileCopier(const QString& sourcePath, const QString& destinationPath, QObject* parent = nullptr);

protected:
    void run() override;

private:
    QString sourcePath;       // 源文件路径
    QString destinationPath;  // 目标文件路径
signals:
    void error();
    void progressChanged();
    void finished();
};

#endif // FILECOPIER_H

2. 实现文件 (filecopier.cpp)

cpp 复制代码
#include "filecopier.h"
#include <QFile>
#include <QDataStream>

FileCopier::FileCopier(const QString& sourcePath, const QString& destinationPath, QObject* parent)
    : QThread(parent), sourcePath(sourcePath), destinationPath(destinationPath) {
    // 初始化
}

void FileCopier::run() {
    QFile sourceFile(sourcePath);
    QFile destinationFile(destinationPath);

    if (!sourceFile.open(QIODevice::ReadOnly)) {
        emit error("无法打开源文件");
        return;
    }

    if (!destinationFile.open(QIODevice::WriteOnly)) {
        emit error("无法创建目标文件");
        sourceFile.close();
        return;
    }

    qint64 fileSize = sourceFile.size();
    qint64 bytesCopied = 0;
    const qint64 bufferSize = 1024 * 1024; // 每次复制 1MB

    QDataStream in(&sourceFile);
    QDataStream out(&destinationFile);

    while (bytesCopied < fileSize) {
        QByteArray buffer = sourceFile.read(bufferSize);
        if (buffer.isEmpty()) {
            break;
        }

        out.writeRawData(buffer.constData(), buffer.size());
        bytesCopied += buffer.size();
    }

    sourceFile.close();
    destinationFile.close();

    emit finished();
}
3. 主窗口类 (widget.h)
cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "filecopier.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget {
    Q_OBJECT

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

private slots:
    void onCopyClicked();

private:
    Ui::Widget* ui;
    FileCopier* fileCopier; // 文件复制线程
};

#endif // WIDGET_H
4. 实现文件 (widget.cpp)
cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QMessageBox>

Widget::Widget(QWidget* parent)
    : QWidget(parent), ui(new Ui::Widget), fileCopier(nullptr) {
    ui->setupUi(this);

    // 连接按钮点击事件
    connect(ui->copyButton, &QPushButton::clicked, this, &Widget::onCopyClicked);
}

Widget::~Widget() {
    delete ui;
}

void Widget::onCopyClicked() {
    QString sourceFilePath = QFileDialog::getOpenFileName(this, "选择源文件", "", "所有文件 (*.*)");
    if (sourceFilePath.isEmpty()) {
        return;
    }

    QString destinationFilePath = QFileDialog::getSaveFileName(this, "选择目标文件", "", "所有文件 (*.*)");
    if (destinationFilePath.isEmpty()) {
        return;
    }

    // 创建文件复制线程
    fileCopier = new FileCopier(sourceFilePath, destinationFilePath, this);

    // 连接信号和槽
    connect(fileCopier, &FileCopier::finished, this, [this]() {
        QMessageBox::information(this, "完成", "文件复制完成");
        fileCopier->deleteLater();
        fileCopier = nullptr;
    });

    connect(fileCopier, &FileCopier::error, this, [this](const QString& message) {
        QMessageBox::critical(this, "错误", message);
        fileCopier->deleteLater();
        fileCopier = nullptr;
    });

    // 启动线程
    fileCopier->start();
}
相关推荐
Scott9999HH3 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社4 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海4 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖5 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区7 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大8 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai8 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜8 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa8 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio