qt--做一个拷贝文件器
创始人
2024-11-21 14:33:54
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  #include  #include  #include  #include  #include  #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  #include  #include   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() << "资源已释放";   } 

四、实验结果

相关内容

热门资讯

一分钟内幕!科乐吉林麻将系统发... 一分钟内幕!科乐吉林麻将系统发牌规律,福建大玩家确实真的是有挂,技巧教程(有挂ai代打);所有人都在...
一分钟揭秘!微扑克辅助软件(透... 一分钟揭秘!微扑克辅助软件(透视辅助)确实是有挂(2024已更新)(哔哩哔哩);1、用户打开应用后不...
五分钟发现!广东雀神麻雀怎么赢... 五分钟发现!广东雀神麻雀怎么赢,朋朋棋牌都是是真的有挂,高科技教程(有挂方法)1、广东雀神麻雀怎么赢...
每日必看!人皇大厅吗(透明挂)... 每日必看!人皇大厅吗(透明挂)好像存在有挂(2026已更新)(哔哩哔哩);人皇大厅吗辅助器中分为三种...
重大科普!新华棋牌有挂吗(透视... 重大科普!新华棋牌有挂吗(透视)一直是有挂(2021已更新)(哔哩哔哩)1、完成新华棋牌有挂吗的残局...
二分钟内幕!微信小程序途游辅助... 二分钟内幕!微信小程序途游辅助器,掌中乐游戏中心其实存在有挂,微扑克教程(有挂规律)二分钟内幕!微信...
科技揭秘!jj斗地主系统控牌吗... 科技揭秘!jj斗地主系统控牌吗(透视)本来真的是有挂(2025已更新)(哔哩哔哩)1、科技揭秘!jj...
1分钟普及!哈灵麻将攻略小,微... 1分钟普及!哈灵麻将攻略小,微信小程序十三张好像存在有挂,规律教程(有挂技巧)哈灵麻将攻略小是一种具...
9分钟教程!科乐麻将有挂吗,传... 9分钟教程!科乐麻将有挂吗,传送屋高防版辅助(总是存在有挂)1、完成传送屋高防版辅助透视辅助安装,帮...
每日必看教程!兴动游戏辅助器下... 每日必看教程!兴动游戏辅助器下载(辅助)真是真的有挂(2025已更新)(哔哩哔哩)1、打开软件启动之...