有个需求就是,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线程只用编写一个槽函数来接收做完的信号并处理就可以了。

Qt5中创建临时的后台线程。的更多相关文章

  1. HandlerThread 创建一个异步的后台线程

    使用HandlerThread几大优点: 1.制作一个后台异步线程,需要的时候就可以丢一个任务给它,使用比较灵活; 2.Android系统提供的,使用简单方便,内部自己封装了Looper+Handle ...

  2. Gunicorn+Flask中重复启动后台线程问题

    假设程序如下: if __name__ == '__main__': t = Thread(target=test) t.start() app.run(host='0.0.0.0',port=808 ...

  3. gunicorn结合django启动后台线程

    preload 为True的情况下,会将辅助线程或者进程开在master里,加重master的负担(master最好只是用来负责监听worker进程) django应用的gunicorn示例:只在主线 ...

  4. 如何在sqlite3连接中创建并调用自定义函数

    #!/user/bin/env python # @Time :2018/6/8 14:44 # @Author :PGIDYSQ #@File :CreateFunTest.py '''如何在sql ...

  5. Qt5中运行后台网络读取线程与主UI线程互交

    项目中有一个需求就是,因为需要请求服务端数据,因为网络的读取会阻塞,所以该过程不能放在Qt中的UI主线程当中,需要用一个后台线程来读取数据,数据准备完毕后 在通过Qt5中的信号槽机制来跨线程的传递数据 ...

  6. Android中UI线程与后台线程交互设计的5种方法

    我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...

  7. 通过使用Web Workers,Web应用程序可以在独立于主线程的后台线程中,运行一个脚本操作。这样做的好处是可以在独立线程中执行费时的处理任务,从而允许主线程(通常是UI线程)不会因此被阻塞/放慢。

    Web Workers API - Web API 接口参考 | MDNhttps://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API ...

  8. Qt中运行后台线程不阻塞UI线程的方案

    有一个想法,一个客户端,有GUI界面的同时也要向网络服务器发送本地采集的数据,通过网络发送数据的接口是同步阻塞的,需要等待服务器响应数据. 如果不采用后台线程的方案,用主UI线程关联一个定时器QTim ...

  9. java中创建线程的方式

    创建线程的方式: 继承thread 实现runnable 线程池 FurureTask/Callable 第一种:继承thread demo1: public class demo1 { public ...

随机推荐

  1. 《UNIX环境高级编程》笔记--环境变量

    ISO C定义了一个函数getenv,可以用其取环境变量值. #include <stdlib.h> char* getenv(const char* name); //返回与name关联 ...

  2. [leetcode]Insert Interval @ Python

    原题地址:https://oj.leetcode.com/problems/insert-interval/ 题意: Given a set of non-overlapping intervals, ...

  3. 如何远程运行PowerShell命令?

    首先, 被remote运行PowerShell的windows必须已经join了domain. 其次, 该Windows的PowerShell必须开启对remote command的接受, 运行下面的 ...

  4. Android 资源混淆 AndResGuard MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. 论文分享|《Universal Language Model Fine-tuning for Text Classificatio》

    https://www.sohu.com/a/233269391_395209 本周我们要分享的论文是<Universal Language Model Fine-tuning for Text ...

  6. 【转载】.NET/C#-uploadify视频文件or大文件上传

    引言 之前使用Uploadify做了一个上传图片并预览的功能,今天在项目中,要使用该插件上传大文件.之前弄过上传图片的demo,就使用该demo进行测试.可以查看我的这篇文章: [Asp.net]Up ...

  7. AVR单片机最小系统 基本硬件线路与分析

    单片机最小系统  单片机最小系统设计 AVR基本硬件线路设计与分析 (ATmega16功能小板) AVR DB-CORE Ver2.3 Atmega16开发板 本站商城提供本最小系统销售:99元 AV ...

  8. 让你的Python代码更加pythonic

    http://wuzhiwei.net/be_pythonic/ 何为pythonic? pythonic如果翻译成中文的话就是很python.很+名词结构的用法在中国不少,比如:很娘,很国足,很CC ...

  9. Mongoose vs mongodb native driver – what to prefer?

      Paul Shan 7th Jun 2015 Mongoose or mongodb native driver, which one to use? This is one of the ini ...

  10. HDU 1541 Stars (线段树)

     Problem Description Astronomers often examine star maps where stars are represented by points on ...