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();
}
相关推荐
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz7 天前
QML Hello World 入门示例
qt
xcyxiner10 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner10 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner11 天前
DicomViewer (添加模型类)3
qt
xcyxiner11 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00613 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术13 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript