qt作业day5
1:是进度条通过线程自己动起来
头文件 (mythread.h
)
#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
)
#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
)
#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
)
#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
)
#ifndef FILECOPIER_H
#define FILECOPIER_H
#include <QThread>
#include <QFile>
class FileCopier : public QThread {
Q_OBJECT
public:
explicit FileCopier(const QString& sourcePath, const QString& destinationPath, QObject* parent = nullptr);
protected:
void run() override;
private:
QString sourcePath; // 源文件路径
QString destinationPath; // 目标文件路径
};
#endif // FILECOPIER_H
2. 实现文件 (filecopier.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
)
#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
)
#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();
}