阅读量:0
一、项目要求
使用线程完善文件拷贝器的操作- 主窗口不能假死
- 主窗口进度条必须能动
- 改写文件大小的单位(自适应)
1TB=1024GB
1GB=1024MB
1MB=1024KB
1KB=1024字节
二、所需技术
1.QFileDialog 文件对话框
QFileDialog也继承了QDialog类,直接使用静态成员函数弹窗,弹窗的结果(选择文件的路径)通过函数的返回值获取。
// 获得一个打开或保存的文件路径 // 参数1 父对象 // 参数2 即windowTitle属性(界面标题) // 参数3 在哪个目录下打开,默认值表示项目的工作目录 // 参数4 文件格式过滤器 // 返回值 选择的文件路径,如果选择失败,返回空字符 QString QFileDialog::getSaveFileName|getOpenFileName (QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString())[static]
需要注意的是,QFileDialog只是一个窗口类,本身不具备任何IO能力。
2.QFileInfo 文件信息类
只需要创建出对象后,通过各种成员函数直接获取文件信息。
// 构造函数 // 参数为文件路径,如果文件非法,仍然可以创建出QFileInfo QFileInfo::QFileInfo(const QString & file) // 判断文件或文件夹是否存在 // 如果存在返回true否则返回false bool QFileInfo::exists() const // 返回文件大小,单位是字节 qint64 QFileInfo::size() const // 返回基础文件名 QString QFileInfo::baseName() const // 返回最近修改日期和时间 QDateTime QFileInfo::lastModified() const // 返回可读性 bool QFileInfo::isReadable() const
3.QFile文件读写类
在Qt中所有IO都都继承自QIODevice类,QIODevice类中规定了最基础的IO相关接口,这些接口虽然在不同的派生类中可能是实现有区别,但调用方式一致。
// 构造函数 // 参数为文件路径,如果是非法路径,也能创建出对象,但是不能正常IO QFile::QFile(const QString & name) // 判断QFile对应的文件是否存在 bool QFile::exists() const // 打开数据流 // 参数为打开的模式 // 返回值为打开的结果 bool QIODevice::open(OpenMode mode)[virtual] // 读取最大长度为maxSize个字节到返回值中 QByteArray QIODevice::read(qint64 maxSize) // 写出数据 // 参数为写出的内容 // 返回值为实际的数据写出字节数,出错返回-1 qint64 QIODevice::write(const QByteArray & byteArray) // 判断是否读到文件尾部 bool QIODevice::atEnd() const[virtual] // 关闭文件流 void QIODevice::close()[virtual] // 清空缓存区 bool QFileDevice::flush() // 返回输入流的大小,单位是字节 qint64 QIODevice::size() const
4.ui界面
三、代码
//dialog.h #ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include <QFileDialog> #include <QMessageBox> #include <QDateTime> #include <QFileInfo> #include <QFile> #include "mythread.h" namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); private: Ui::Dialog *ui; QString readPath; QString writePath; void prinFileInfo(); void copy(); MyThread *ct; private slots: void btnsClickedSlot(); void valueSlot(int); }; #endif // DIALOG_H
//mythread.h #ifndef MYTHREAD_H #define MYTHREAD_H #include <QThread> #include <QDebug> #include <QFile> class MyThread : public QThread { Q_OBJECT public: explicit MyThread(QObject *parent = 0); ~MyThread(); bool getRunningState() const; void setRunningState(bool value); void Pathget(QString, QString); signals: void valueSignal(int); public slots: private: QString treadPath; QString twritePath; bool runningState;// 状态标记 protected: void run(); }; #endif // MYTHREAD_H
//dialog.c #include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); connect(ui->pushButtonOpen,SIGNAL(clicked()),this,SLOT(btnsClickedSlot())); connect(ui->pushButtonSave,SIGNAL(clicked()),this,SLOT(btnsClickedSlot())); connect(ui->pushButtonCopy,SIGNAL(clicked()),this,SLOT(btnsClickedSlot())); } Dialog::~Dialog() { delete ui; } void Dialog::prinFileInfo() { QFileInfo info(readPath); if(!info.exists()) return; qint64 size=info.size(); qreal size2; QString text; if(size<1024) { size2=size; QString text=QString ::number(size2); text.prepend("文件大小:").append("字节"); ui->textBrowserOpen->append(text); } else if(size>=1024 && size<1048576) { size2=size/1024; QString text=QString ::number(size2); text.prepend("文件大小:").append("K字节"); ui->textBrowserOpen->append(text); } else if(size>=1048576&&size<1073741824) { size2=size/1048576; QString text=QString ::number(size2); text.prepend("文件大小:").append("M字节"); ui->textBrowserOpen->append(text); } else if(size>=1073741824&&size<1099511627776) { size2=size/1073741824; QString text=QString ::number(size2); text.prepend("文件大小:").append("G字节"); ui->textBrowserOpen->append(text); } text=info.baseName(); text.prepend("文件名称:"); ui->textBrowserOpen->append(text); text=info.lastModified().toString("修改时间:yyyy-MM-dd hh:mm:ss"); ui->textBrowserOpen->append(text); bool result=info.isReadable(); if(result) ui->textBrowserOpen->append("文件可读"); else ui->textBrowserOpen->append("文件不可读"); } void Dialog::copy() { if(readPath=="") { QMessageBox::warning(this,"提示","请选择要读取的文件"); return; } else if(writePath=="") { QMessageBox::warning(this,"提示","请选择要保存的文件"); return; } QFile readFile(readPath); QFile writeFile(writePath); readFile.open(QIODevice::ReadOnly); writeFile.open(QIODevice::WriteOnly); writeFile.flush(); readFile.close(); writeFile.close(); } void Dialog::btnsClickedSlot() { if(ui->pushButtonOpen==sender()) { QString filter="所有文件(*.*);;Qt(*.cpp *.pro *.h *.ui)";//符号都是英语符号,用于检索 QString path=QFileDialog::getOpenFileName(this,"打开","C:/",filter); if(path != "") { ui->textBrowserOpen->append(path); readPath=path; prinFileInfo(); } else if (readPath == "") { QMessageBox::warning(this,"提示","请选择要打开的文件!"); return; } } else if(ui->pushButtonSave==sender()) { QString filter="所有文件(*.*);;Qt(*.cpp *.pro *.h *.ui)"; QString path=QFileDialog::getSaveFileName(this,"保存","C:/",filter); if(path != "") { ui->textBrowserSave->append(path); writePath=path; } else if (writePath == "") { QMessageBox::warning(this,"提示","请选择要保存的文件!"); return; } } else if(ui->pushButtonCopy==sender()) { // 创建子线程对象并启动 if(ui->pushButtonCopy->text() == "开始拷贝") { copy(); ct = new MyThread(this); connect(ct,SIGNAL(valueSignal(int)), this,SLOT(valueSlot(int))); ct->start(); ui->pushButtonCopy->setText("停止拷贝"); } else if (ui->pushButtonCopy->text() == "停止拷贝") { ui->pushButtonCopy->setText("开始拷贝"); ct->setRunningState(false); } } } void Dialog::valueSlot(int value) { ui->progressBar->setValue(value); if(value == 100) { // 释放按钮 ui->pushButtonCopy->setEnabled(true); this->hide();// 隐藏主窗口,只是看不到 this->show();// 显示主窗口 QMessageBox::information(this,"通知","文件拷贝完毕"); } }
//mythread.c #include "mythread.h" MyThread::MyThread(QObject *parent) : QThread(parent) { setRunningState(true); } MyThread::~MyThread() { } bool MyThread::getRunningState() const { return runningState; } void MyThread::setRunningState(bool value) { runningState = value; } void MyThread::run() { for(int i = 0 ;i <= 100 && runningState;i++) { QThread::msleep(100); emit valueSignal(i); } qDebug() << "资源已释放"; }