【QML】QML复制文件或文件夹,显示进度,多线程复制,索尼xperia t
cpugpu芯片开发光刻机
跨学科知识体系
2
文件名:【QML】QML复制文件或文件夹,显示进度,多线程复制,索尼xperia t
【QML】QML复制文件或文件夹,显示进度,多线程复制
1. 效果 可以显示复制文件和文件夹的进度 复制文件: bool copyFileFunc(QString _from, QString _to);复制文件夹:bool copyDirectoryFiles(const QString &_from, const QString &_to);举例: //复制文件copyhelper.copyFileToDir("./test.txt", "d:/copytest/dir/test1.txt");//复制文件夹copyhelper.copyFileToDir("./copyTest", "d:/copytest/dir/copyTest1"); 2. QML代码 import QtQuick 2.15import QtQuick.Window 2.15import QtQuick.Controls 2.15import QtQuick.Controls.Styles 1.4import QtQuick.Controls 1.4Window {width: 640height: 480visible: truetitle: qsTr("copy file")Rectangle{id: _progresswidth: parent.widthheight: parent.height / 2border.color: "blue"border.width: 1property string processv: "0"ProgressBar {id: pbarwidth: 480;height: 30minimumValue: 0maximumValue: 100value: 0anchors.centerIn: parentstyle: ProgressBarStyle{id: progressStylebackground: Rectangle{color: "lightgrey"radius: 6}progress: Rectangle{color: control.value === 100 ? "#b1d946" :"#4c7aff"radius: 6}panel: Item{//通过panel属性,可以加载 progress Text background等组件//设置外边框implicitWidth: 480;implicitHeight: 15;Loader{anchors.fill: parent;sourceComponent: background;}Loader{id: progressLoader;anchors.top: parent.top;anchors.left: parent.left;anchors.bottom: parent.bottom;anchors.margins: 0;z: 1;width: currentProgress * (parent.width);sourceComponent: progressStyle.progress;}Text{color: "black"text: _progress.processvz: 2anchors.centerIn: parent}}}}}Button{width: 200height: 100anchors.top: _progress.bottomanchors.horizontalCenter: _progress.horizontalCenteranchors.topMargin: 20text: qsTr("开始复制")onClicked: {console.log("开始复制")//复制文件//copyhelper.copyFileToDir("./test.txt", "d:/copytest/dir/test1.txt");//复制文件夹copyhelper.copyFileToDir("./copyTest", "d:/copytest/dir/copyTest1");}}Connections{target: copyhelperfunction onQmlCopyProgress(value){pbar.value = value;_progress.processv = value + "%";}}} 3. main.c代码 #include <QGuiApplication>#include <QtQml>#include <QApplication>#include <QQmlApplicationEngine>#include "copyhelper.h"int main(int argc, char *argv[]){#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);#endifQApplication app(argc, argv);QQmlApplicationEngine engine;engine.rootContext()->setContextProperty("copyhelper", new CopyHelper);const QUrl url(QStringLiteral("qrc:/main.qml"));QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);engine.load(url);return app.exec();} 4. .pro代码 QT += quick qml widgets core# You can make your code fail to compile if it uses deprecated APIs.# In order to do so, uncomment the following line.#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += \copyfiles.cpp \copyhelper.cpp \main.cppRESOURCES += qml.qrc# Additional import path used to resolve QML modules in Qt Creator's code modelQML_IMPORT_PATH =# Additional import path used to resolve QML modules just for Qt Quick DesignerQML_DESIGNER_IMPORT_PATH =# Default rules for deployment.qnx: target.path = /tmp/$${TARGET}/binelse: unix:!android: target.path = /opt/$${TARGET}/bin!isEmpty(target.path): INSTALLS += targetHEADERS += \copyfiles.h \copyhelper.h 5. C++代码 创建两个类 CopyHelper 和 CopyFilesCopyFiles中是具体实现CopyHelper 为了实现多线程 5.1 copyfile.h #ifndef COPYFILES_H#define COPYFILES_H#include <QObject>#include <QDebug>#include <QFile> //文件操作#include <QDataStream> //数据流#include <QThread> //线程class CopyFiles : public QObject{Q_OBJECTpublic://只能显式构造/*** QString _srcFilePath : 源文件路径* QString _dstPath : 目标路径* QObject *parent = 0 : 父对象指针,默认为空*/explicit CopyFiles(QString _srcFilePath, QString _dstPath,QObject *parent = 0);signals:void startCopyFile(QString, QString); //复制文件信号void startCopyDir(QString, QString); //复制文件夹信号void copyProcess(QString); //复制文件进度信号public slots:/*** @brief copyFileFunction : 复制文件信号处理槽* @param _from : 源文件名* @param _to : 目标文件名* @return bool : 返回类型 成功返回true 失败返回false*/bool copyFileFunc(QString _from, QString _to);/*** @brief copyDirectoryFiles : 复制文件夹* @param _from : 源文件夹路径* @param _to : 目标文件夹路径* @return : 成功返回true 失败返回false*/bool copyDirectoryFiles(const QString &_from, const QString &_to);private:bool m_firstRead = true;qint64 m_total = 0;qint64 m_now = 0;private:void getDirSize(QString _dir, qint64* size);bool copyFile(QString _from, QString _to, qint64* nowSize, qint64 totalSize);};#endif // COPYFILES_H 5.2 copyfile.cpp #include "copyfiles.h"#include "qfileinfo.h"#include <QFile>#include <QDir>CopyFiles::CopyFiles(QString _srcFilePath, QString _dstPath, QObject *parent){qDebug() << QThread::currentThreadId() << _srcFilePath << _dstPath;}bool CopyFiles::copyFileFunc(QString _from, QString _to){qint64 fileSize = 0;qint64 totalCopySize = 0;//文件夹创建QFileInfo fininfo(_to);QDir path;if(!path.exists(fininfo.absolutePath())){path.mkdir(fininfo.absolutePath());}//文件对象QFile tofile;tofile.setFileName(_to);QFile fromfile;fromfile.setFileName(_from);fileSize = fromfile.size();/* 复制文件 */return copyFile(_from, _to, &totalCopySize, fileSize);}bool CopyFiles::copyDirectoryFiles(const QString &_from, const QString &_to){QDir sourceDir(_from);QDir targetDir(_to);qDebug() << "copy form" <<_from << _to;/* 如果目录不存在,则创建 */if(!targetDir.exists()){if(!targetDir.mkdir(targetDir.absolutePath())){return false;}}QFileInfoList fileInfoList = sourceDir.entryInfoList();if(m_firstRead){qDebug() << "copyDirectoryFiles count:" << fileInfoList.count();/* 获取文件夹总大小 */m_total = 0;getDirSize(_from, &m_total);/* 标志位 */m_now = 0;m_firstRead = false;qDebug() << "copyDirectoryFiles: " << m_total << m_now;/* 复制完成 */if(m_now == m_total){m_firstRead = true;}}foreach(QFileInfo fileInfo, fileInfoList){if(fileInfo.fileName() == "." || fileInfo.fileName() == ".."){continue;}/* 当前为目录递归进行copy */if(fileInfo.isDir()){if(!copyDirectoryFiles(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()))){return false;}}/* 复制文件 */else{if(!copyFile(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()), &m_now, m_total)){return false;}}}return true;}void CopyFiles::getDirSize(QString _dir, qint64* size){QDir sourceDir(_dir);QFileInfoList fileInfoList = sourceDir.entryInfoList();/* 遍历文件夹 */foreach(QFileInfo fileInfo, fileInfoList){if(fileInfo.isFile()){if(fileInfo.fileName() != "." && fileInfo.fileName() != ".."){*size += fileInfo.size();qDebug() << "1-----" << fileInfo.fileName() << *size;}}else if(fileInfo.isDir()){/* 递归 */if(fileInfo.fileName() != "." && fileInfo.fileName() != ".."){getDirSize(fileInfo.filePath(), size);qDebug() << "2-----" << fileInfo.fileName() <<fileInfo.filePath();}}}}bool CopyFiles::copyFile(QString _from, QString _to, qint64* nowSize, qint64 totalSize){qDebug() << "子线程ID:" << QThread::currentThreadId();char * byteTemp = new char[1024*8]; //每次复制8kqint64 fileSize = 0;qint64 totalCopySize = 0;//文件夹创建QFileInfo fininfo(_to);QDir path;if(!path.exists(fininfo.absolutePath())){path.mkdir(fininfo.absolutePath());}//文件对象QFile tofile;tofile.setFileName(_to);QFile fromfile;fromfile.setFileName(_from);//文件读取判断if(!tofile.open(QIODevice::WriteOnly)){qDebug() << "无法打开目标文件1";delete[](byteTemp);return false;}if(!fromfile.open(QIODevice::ReadOnly)){qDebug() << "无法打开目标文件2";delete[](byteTemp);return false;}//文件大小QDataStream out(&tofile);//文件流out.setVersion(QDataStream::Qt_4_0);fileSize = fromfile.size();QDataStream in(&fromfile);in.setVersion(QDataStream::Qt_4_0);qDebug() << "文件总大小:" << fileSize << " / " << QString::number(totalSize);//循环复制文件while(!in.atEnd()){qint64 readSize = 0;//每次读取8kreadSize = in.readRawData(byteTemp, 1024*8); //读取复制文件到缓存并返回读取的实际大小out.writeRawData(byteTemp, readSize); //写到输出流totalCopySize += readSize; //累计已复制大小*nowSize += readSize;int tmpVal = *nowSize / (double)totalSize * 100;//复制进度计算emit copyProcess(QString::number(tmpVal)); //发射当前复制进度//qDebug() << "now:" << *nowSize;}//复制完成if(totalCopySize == fileSize){tofile.setPermissions(QFile::ExeUser);//设置文件权限tofile.close(); //关闭文件流fromfile.close(); //关闭文件流delete[](byteTemp);return true; //返回复制结果-成功}else{delete[](byteTemp);return false; //返回复制结果-失败}} 5.3 copyhelper.h #ifndef COPYHELPER_H#define COPYHELPER_H#include <QObject>class CopyHelper : public QObject{Q_OBJECTpublic:explicit CopyHelper(QObject *parent = 0);public:/*** @brief copyFileToDir 复制文件到目录* @return QString 返回字符串*/Q_INVOKABLE QString copyFileToDir(QString _from, QString _to);signals:/*** @brief qmlCopyProgress 供qml使用的复制文件进度信号* @param value*/void qmlCopyProgress(QString value);private :/*** @brief testReadFile 测试读取文件*/void testReadFile();private slots:/*** @brief reciveCopyProgress 接收文件进度槽*/void reciveCopyProgress(QString);};#endif // COPYHELPER_H 5.4 copyhelper.cpp #include "copyhelper.h"#include <QDebug>#include <QFile>#include <QDataStream>#include <QThread>#include <QFileInfo>#include "copyfiles.h"CopyHelper::CopyHelper(QObject *parent) : QObject(parent){qDebug() << "文件复制助手线程ID:" <<QThread::currentThreadId();}//复制文件到目录QString CopyHelper::copyFileToDir(QString _from, QString _to){//构造复制文件类CopyFiles * m_pCopyFile = new CopyFiles(_from, _to);//复制文件子线程QThread * m_pCopyFilethread = new QThread();m_pCopyFile->moveToThread(m_pCopyFilethread); //子线程中执行文件复制//连接文件复制信号connect(m_pCopyFile,SIGNAL(startCopyFile(QString,QString)),m_pCopyFile,SLOT(copyFileFunc(QString,QString)));connect(m_pCopyFile,SIGNAL(startCopyDir(QString,QString)),m_pCopyFile,SLOT(copyDirectoryFiles(QString,QString)));connect(m_pCopyFile,SIGNAL(copyProcess(QString)),this,SLOT(reciveCopyProgress(QString)));//链接线程完成信号connect(m_pCopyFilethread, SIGNAL(finished()), m_pCopyFilethread, SLOT(deleteLater()));connect(m_pCopyFilethread, &QThread::finished, m_pCopyFilethread, &QObject::deleteLater);//启动复制线程m_pCopyFilethread->start();//判断文件还是文件夹QFileInfo fileInfo(_from);if(fileInfo.isDir()){//发射文件夹复制开始信号emit m_pCopyFile->startCopyDir(_from, _to);}else{//发射文件复制开始信号emit m_pCopyFile->startCopyFile(_from, _to);}return "复制成功";}//测试读取文件void CopyHelper::testReadFile(){//测试复制文件QString strFileName = "d:/test.rar";if (!QFile::exists(strFileName)){return;} //文件不存在QFile file(strFileName);if (!file.open(QFile::ReadOnly)){return;}//文件无法打开QDataStream in(&file); //数据流int nFileSize = file.size();//文件大小int p = 0; //当前复制位置while (!in.atEnd()) {char buffer [8192];int readsize = 0;readsize = in.readRawData(buffer,8192);p = file.pos();qDebug() <<"文件总大小:"<<nFileSize<<"读取大小"<<readsize<<" 当前复制进度"<<QString::number(p);}}//接收文件进度void CopyHelper::reciveCopyProgress(QString value){emit qmlCopyProgress(value);//发射接收文件进度} 6. 参考 QML复制文件并显示进度Qt制作有进度条的拷贝文件夹和文件的小Demo
同类推荐
-

【PS】制作 素描 + 遗照,狗狗资源搜索
查看 -

【PTA天梯赛CCCC -2017决赛L2-3】图着色问题 (25 分)(图染色),星号查看
查看 -

【PUSDN】WebStorm中报错Switch language version to React JSX,akg k402
查看 -

【PUSDN】centos查看日志文件内容,包含某个关键字的前后5行日志内容,centos查看日志的几种方法,小影霸gt430
查看 -

【PUSDN】java中easyexcel导入导出带有图片的Excel(main方法方式),馅饼网
查看 -

【PWN】学习笔记(三)【返回导向编程】(下),sony zx1
查看 -

【Proteus】绘制简单的电路图,三星es70
查看 -

【Proteus仿真】【Arduino单片机】RGB彩灯,迅雷色
查看 -

【Proteus仿真】【Arduino单片机】SG90舵机控制,ipod shuffle 4
查看