作业
代码
MyQThread.h
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread(QObject *parent = nullptr);
protected:
void run() override;
signals:
//向ui界面发送的 "复制进度" 的信号
void copy_process_signal(int index);
public slots:
// "复制"信号的槽
void do_copyfile_slots(QString oldfilename,QString newfilename);
private:
QString oldfilename;
QString newfilename;
bool start_copy_flag=0;
};
#endif // MYTHREAD_H
MyQThread.cpp
MyThread::MyThread(QObject *parent)
:QThread(parent)
{
}
// "槽"
void MyThread::do_copyfile_slots(QString oldfilename,QString newfilename)
{
//进入此函数,说明ui界面拖入了文件,需要进行文件复制
this->oldfilename=oldfilename; //源文件路径
this->newfilename=newfilename; //目标文件路径
start_copy_flag=1; //打开标志位
}
void MyThread::run()
{
qDebug() << "子进程进入run函数";
while(1)
{
if(start_copy_flag)
{;
//文件复制(准备阶段)
QFile old_file(oldfilename); //拆功能键QFile对象
QFile new_file(newfilename);
old_file.open(QIODevice::ReadOnly); //打开文件
new_file.open(QIODevice::WriteOnly);
char data[4096];
qint64 filesize = old_file.size(); //文件总大小
qint64 readsize=0; //已读大小
int index_backup=0; //任务进度
//文件复制(执行阶段)
while(1)
{
//读取数据
qint64 real_read__size = old_file.read(data,4096);
//判断是否读完
if(real_read__size == 0){break;} //读取到的字节数为0 说明读取完毕,退出
//计算"处理进度"
readsize+=real_read__size; //已经读取的字节总数
int index =readsize * 100 / filesize; //"处理进度"
//告知ui界面 当前“处理进度”
if(index - index_backup > 1) //仅当"处理进度"发生变化x时
{
copy_process_signal(index); //才发出信号,让ui重新回执进度
qDebug() << "复制进度" << index << " 读取总字节" << readsize << " 文件总大小" << filesize;
}
//写入数据
new_file.write(data,real_read__size);
}
copy_process_signal(100); //运行到此说明复制完毕,手动将进度设置为100
old_file.close();
new_file.close();
qDebug() << "复制完毕";
start_copy_flag = 0; //关闭标志位
}
}
exec(); // 启动事件循环
}
Widget.h
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void dropEvent(QDropEvent *event) override; //释放
void dragEnterEvent(QDragEnterEvent *event) override; //进入
private slots:
void update_copy_process(int index);
signals:
void copyfile_signal(QString oldfilename,QString newfilename);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
Widget.cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setAcceptDrops(1); //设置允许拖拽
MyThread* thread = new MyThread(this);
// "复制文件"
QObject::connect(this,&Widget::copyfile_signal,thread,&MyThread::do_copyfile_slots);
// "任务进度"
QObject::connect(thread,&MyThread::copy_process_signal,this,&Widget::update_copy_process);
//滑块相关设置
QString qss = "QSlider::sub-page{background-color:blue} QSlider::groove:horizontal{background-color:white}";
ui->slider->setStyleSheet(qss);
thread->start();
}
Widget::~Widget()
{
delete ui;
}
//拖入
void Widget::dragEnterEvent(QDragEnterEvent *event)
{
event->acceptProposedAction(); //接收拖入
}
//释放
void Widget::dropEvent(QDropEvent *event)
{
//从事件中解析文件名
const QMimeData* mData = event->mimeData(); //获取其中mimeData
QList<QUrl> urls_list = mData->urls(); //转为urls_list 文件信息村饭到这个容器中
QUrl url = urls_list[0]; //读取容器中第一条数据
QString oldfilename = url.toLocalFile(); //url 转 "文件名"
//从对话框中获取文件名
QString newfilename = QFileDialog::getSaveFileName(this,"保存文件","E:\\DAY5","AllFiles (*);;Images (*.png *.xpm *.jpg)");
//数据部分,交由进程处理
copyfile_signal(oldfilename,newfilename);
}
//槽函数(子进程任务进度 信号)
void Widget::update_copy_process(int index)
{
//设置进度条
ui->slider->setValue(index);
}
效果