QT-异步编程
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);
}