将程序压缩为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);
}
}