qt--做一个拷贝文件器

avatar
作者
筋斗云
阅读量:0

一、项目要求

使用线程完善文件拷贝器的操作
  1. 主窗口不能假死
  2. 主窗口进度条必须能动
  3. 改写文件大小的单位(自适应)

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() << "资源已释放";   } 

四、实验结果

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!