qt--做一个拷贝文件器

一、项目要求

使用线程完善文件拷贝器的操作

  1. 主窗口不能假死
  2. 主窗口进度条必须能动
  3. 改写文件大小的单位(自适应)

1TB=1024GB

1GB=1024MB

1MB=1024KB

1KB=1024字节

二、所需技术

1.QFileDialog 文件对话框

QFileDialog也继承了QDialog类,直接使用静态成员函数弹窗,弹窗的结果(选择文件的路径)通过函数的返回值获取。

cpp 复制代码
// 获得一个打开或保存的文件路径
// 参数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 文件信息类

只需要创建出对象后,通过各种成员函数直接获取文件信息。

cpp 复制代码
// 构造函数
// 参数为文件路径,如果文件非法,仍然可以创建出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相关接口,这些接口虽然在不同的派生类中可能是实现有区别,但调用方式一致。

cpp 复制代码
// 构造函数
// 参数为文件路径,如果是非法路径,也能创建出对象,但是不能正常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界面

三、代码

cpp 复制代码
//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
cpp 复制代码
//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
cpp 复制代码
//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,"通知","文件拷贝完毕");
    }
}
cpp 复制代码
//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() << "资源已释放";
 
}

四、实验结果

相关推荐
飞飞-躺着更舒服26 分钟前
【QT】实现电子飞行显示器(改进版)
开发语言·qt
武昌库里写JAVA41 分钟前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
CYBEREXP20081 小时前
MacOS M3源代码编译Qt6.8.1
c++·qt·macos
ZSYP-S1 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos1 小时前
c++------------------函数
开发语言·c++
程序员_三木2 小时前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
是小崔啊2 小时前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama2 小时前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全2 小时前
Java的基础概念(一)
java·开发语言·python
liwulin05062 小时前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr