将程序压缩为zip格式后添加到资源文件,安装时使用quazip从资源文件解压到指定目录,并且将解压放在子线程,避免UI卡主。在做安装包时要使用静态编译,要不然安装包还是需要一大堆dll文件。目录结构如下:
主要代码:
#ifndef UNCOMPRESSTHREAD_H #define UNCOMPRESSTHREAD_H #include <QObject> #include <QThread> class UncompressThread : public QObject { Q_OBJECT public: explicit UncompressThread(QObject *parent = 0); ~UncompressThread(); private: bool SubFunExtractFile(QString strInFile, QString strOutFile); bool SubFunExtractDir(QString strInFile, QString strOutPath); bool SubFubExtractZipFile(QString strInFile, QString strInFilePath, QString strOutPath); void setRegValue(QString strPath, QString strItemName, QString strItemData); signals: void WorkerThreadFinishSig(); void SendUncompressInfomationSig(QString mes); void SendCurrentFileSig(QString file); void SendProgressValueSig(int value); public slots: void uncompressFile(QString file,QString path); private: QThread mThread; }; #endif // UNCOMPRESSTHREAD_H
#include "uncompressthread.h" #include "./quazip/JlCompress.h" #include <QDir> #include <QStandardPaths> #include <QDebug> #include <QSettings> #include <QCoreApplication> UncompressThread::UncompressThread(QObject *parent) : QObject(parent) { this->moveToThread(&mThread); mThread.start(); } UncompressThread::~UncompressThread() { mThread.quit(); mThread.wait(); } void UncompressThread::uncompressFile(QString file,QString path) { QString m_strAppPath =path; //QString strInFileName /*= "D:\\QtCore\\Uncompress\\release\\Qt5.7-static"*/; QStringList OutFileList; OutFileList<< file; qDebug()<<OutFileList; for(int i = 0;i < OutFileList.count();i++) { //SubFunExtractFile(strInFileName, OutFileList.at(i)); bool bRet = SubFunExtractDir(OutFileList.at(i), m_strAppPath); if (bRet != true) { SendUncompressInfomationSig(QStringLiteral("提取文件错误.")); } SendUncompressInfomationSig(QStringLiteral("提取文件完成.")); } emit WorkerThreadFinishSig(); } bool UncompressThread::SubFunExtractFile(QString strInFile, QString strOutFile) { QFile infile(strInFile); if (!infile.open(QIODevice::ReadOnly)) { return(false); } QByteArray data = infile.readAll(); QFile outfile(strOutFile); if (!outfile.open(QIODevice::WriteOnly | QIODevice::Append)) { return(false); } outfile.write(data); infile.close(); outfile.close(); return(true); } bool UncompressThread::SubFunExtractDir(QString strInFile, QString strOutPath) { QuaZip zipInFile(strInFile); if (!zipInFile.open(QuaZip::mdUnzip)) { qDebug()<<"zipInFile open failed"; return(false); } int nFileCount = zipInFile.getEntriesCount(); int nFileProgress = 0; bool hasFile = zipInFile.goToFirstFile(); while(hasFile) { bool bRet = SubFubExtractZipFile(zipInFile.getZipName(), zipInFile.getCurrentFileName(), strOutPath); if (bRet != true) { qDebug()<<"SubFubExtractZipFile failed"; return(false); } nFileProgress++; emit SendProgressValueSig(100*nFileProgress/nFileCount); bRet = zipInFile.goToNextFile(); if (bRet != true) break; } return(true); } bool UncompressThread::SubFubExtractZipFile(QString strInFile, QString strInFilePath, QString strOutPath) { QuaZipFile infile(strInFile, strInFilePath); if (!infile.open(QIODevice::ReadOnly)) { return(false); } QByteArray data = infile.readAll(); QString outPath = strOutPath +'\\'+ strInFilePath; if (outPath.endsWith("/") == true) { QDir appDir(outPath); if (appDir.exists() != true) { appDir.mkpath(outPath); } return(true); } outPath.remove('\\'); QFile outfile(outPath); QString file = outPath.remove(QStandardPaths::standardLocations(QStandardPaths::ConfigLocation)[0]); emit SendCurrentFileSig(file); SendUncompressInfomationSig(QStringLiteral("正在提取文件")+file); if (!outfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { return(false); } outfile.write(data); infile.close(); outfile.close(); return(true); } void UncompressThread::setRegValue(QString strPath, QString strItemName, QString strItemData) { QSettings reg(strPath, QSettings::NativeFormat); QStringList regValue = reg.value(strItemName).toString().split(";"); if(regValue.contains(strItemData)) { return; } if(strItemName == "Path") { reg.setValue(strItemName, reg.value(strItemName).toString()+";"+strItemData); } else { reg.setValue(strItemName, strItemData); } }