有个需求就是,GUI图形界面在上传文件到服务器的时候,需要用zip命令行打包,因为文件很多的时候,zip命令打包需要计算很长时间,所以把这样计算量大的任务分离到后台线程比较合适,然后任务完成,以信号槽机制来通知前台

UI线程处理结果。所以这个线程是需要销毁的,跟之前的一直在运行的后台线程接收网络数据的不一样。

压缩文件的任务类  H文件:

 #include <QObject>
#include <QStringList> class ZipUpdatePackageTask : public QObject
{
Q_OBJECT public:
ZipUpdatePackageTask();
~ZipUpdatePackageTask(); public slots:
void doZip();
void beZipFiles(const QStringList& files);
signals:
void zipFinished();
void zipPackageInfo(const QString& fileName, const QString& md5, const QString& size); private:
bool beZipFilesIsEmpty();
void deleteHistoryZip(const QString& targetPackage);
void toBeZipFilesArguments(QString &files);
void startZipTask(QString zipExePath, QString targetPackage, QString files);
QString getFileMD5(const QString& targetZipPackage);
QString getFileSize(const QString& targetZipPackage);
private:
QStringList m_files;
};

压缩任务类的 cpp文件:

 #include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QProcess>
#include <QCryptographicHash> ZipUpdatePackageTask::ZipUpdatePackageTask()
{
} ZipUpdatePackageTask::~ZipUpdatePackageTask()
{
} void ZipUpdatePackageTask::doZip()
{
QString appDir = qApp->applicationDirPath();
QString zipExePath = QString("%1/%2").arg(appDir).arg("zip.exe");
if (QFile::exists(zipExePath) && !beZipFilesIsEmpty())
{ QString targetZipPackage = QString("%1/%2").arg(appDir).arg("update.zip");
QString beZipFiles; toBeZipFilesArguments(beZipFiles);
deleteHistoryZip(targetZipPackage);
startZipTask(zipExePath, targetZipPackage, beZipFiles); if (QFile::exists(targetZipPackage))
{
QString size = getFileSize(targetZipPackage);
QString md5 = getFileMD5(targetZipPackage); emit zipPackageInfo(targetZipPackage, md5, size); } } emit zipFinished();
} void ZipUpdatePackageTask::beZipFiles(const QStringList& files)
{
m_files.clear();
m_files = files;
} bool ZipUpdatePackageTask::beZipFilesIsEmpty()
{
return m_files.isEmpty();
} void ZipUpdatePackageTask::deleteHistoryZip(const QString& targetPackage)
{
if (QFile::exists(targetPackage))
{
QDir dir;
dir.remove(targetPackage);
}
} void ZipUpdatePackageTask::toBeZipFilesArguments(QString &files)
{
for (auto file : m_files)
{
files.append(file);
files.append(" ");
}
} void ZipUpdatePackageTask::startZipTask(QString zipExePath, QString targetPackage, QString files)
{
QProcess* zipProcesss = new QProcess;
//zip a [zip_package_path_name] [file1Path]...[fileNPath]
QString command = QString("%1 a %2 %3").arg(zipExePath).arg(targetPackage).arg(files);
zipProcesss->start(command);
zipProcesss->waitForFinished(-);
} QString ZipUpdatePackageTask::getFileMD5(const QString& targetZipPackage)
{
QString md5;
QFile file(targetZipPackage);
if (file.open(QFile::ReadOnly))
{
QCryptographicHash hash(QCryptographicHash::Md5);
if (hash.addData(&file))
{
md5 = QString(hash.result().toHex());
} file.close();
}
return md5;
} QString ZipUpdatePackageTask::getFileSize(const QString& targetZipPackage)
{
QFileInfo fileInf(targetZipPackage);
return QString::number(fileInf.size());
}

以下是创建这个后台压缩线程的槽函数,当压缩上传的button点击,就调用以下这个槽函数:

 void StatisticsWidget::slotUploadPackage()
{
QThread *zipThread = new QThread;
ZipUpdatePackageTask* task = new ZipUpdatePackageTask(); QStringList beZipFiles;
for (int listRow = ; listRow < ui->updateFileList->count(); ++listRow)
{
beZipFiles << ui->updateFileList->item(listRow)->text();
} task->beZipFiles(beZipFiles);
task->moveToThread(zipThread); connect(zipThread, &QThread::started, task, &ZipUpdatePackageTask::doZip); connect(task, SIGNAL(zipFinished()), zipThread, SLOT(quit()));
connect(task, &ZipUpdatePackageTask::zipPackageInfo, this, &StatisticsWidget::slotZipFinished,Qt::QueuedConnection); //automatically delete thread and task object when work is done:
connect(zipThread, SIGNAL(finished()), task, SLOT(deleteLater()));
connect(zipThread, SIGNAL(finished()), zipThread, SLOT(deleteLater()));
zipThread->start();
}

注意,以上代码都是临时任务和线程,当任务完成以后,由于设置了相应的信号槽,会自动删除。 任务线程做完该做的事儿,发出了一个zipPackageInfo的信号就销毁了。UI线程只用编写一个槽函数来接收做完的信号并处理就可以了。

最新文章

  1. 高版本-&gt;低版本迁移,低版本客户端连接高版本数据库EXP导出报错EXP-00008,ORA-01455,EXP-00000
  2. CAD2008 启动慢 卡住
  3. JS中简单原型的使用
  4. Java Decompiler 反编译工具下载地址及JD-Eclipse设置菜单翻译
  5. RDIFramework.NET ━ 9.4 角色管理 ━ Web部分
  6. html格式化
  7. 循环语句while与for的穷举迭代
  8. http协议传输二进制数据以及对输入流(php://input)和http请求的理解
  9. 涨姿势:创业做一个App需要花多少钱(8个人,6个月,就要100万,附笔记心得)
  10. ubuntu下android源码下载
  11. Linux likely unlikely
  12. 给 Android 初学者的 Gradle 知识普及
  13. 自己动手写CPU之第七阶段(7)——乘累加指令的实现
  14. SQL Profile 总结(一)
  15. [置顶] MyEclipse显示中文界面,在线安装教程
  16. 训练 smallcorgi/Faster-RCNN_TF 模型(附ImageNet model百度云下载地址)
  17. python之路--小数据池,再谈编码,is和 == 的区别
  18. 论文阅读:Learning Visual Question Answering by Bootstrapping Hard Attention
  19. 自定义自己的jQury插件
  20. WinForm通过操作注册表实现限制软件使用次数的方法

热门文章

  1. go语言之进阶篇主协程先退出导致子协程没来得及调用
  2. Android -- setWillNotDraw()
  3. JAVA-SpringMVC开发第一个应用
  4. 3分钟搞定Linux系统正则表达式
  5. Sublime 3156 LICENSE key
  6. Hibernate中得fetch
  7. Refuses to install for WTP10
  8. GOOD BLOG URL
  9. ScrollView嵌套ListView,ListView完全展开及makeMeasureSpec测量机制原理分析
  10. Discuz常见小问题-如何人为地添加用户并分配小组