Qt5中创建临时的后台线程。
有个需求就是,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中创建临时的后台线程。的更多相关文章
- HandlerThread 创建一个异步的后台线程
使用HandlerThread几大优点: 1.制作一个后台异步线程,需要的时候就可以丢一个任务给它,使用比较灵活; 2.Android系统提供的,使用简单方便,内部自己封装了Looper+Handle ...
- Gunicorn+Flask中重复启动后台线程问题
假设程序如下: if __name__ == '__main__': t = Thread(target=test) t.start() app.run(host='0.0.0.0',port=808 ...
- gunicorn结合django启动后台线程
preload 为True的情况下,会将辅助线程或者进程开在master里,加重master的负担(master最好只是用来负责监听worker进程) django应用的gunicorn示例:只在主线 ...
- 如何在sqlite3连接中创建并调用自定义函数
#!/user/bin/env python # @Time :2018/6/8 14:44 # @Author :PGIDYSQ #@File :CreateFunTest.py '''如何在sql ...
- Qt5中运行后台网络读取线程与主UI线程互交
项目中有一个需求就是,因为需要请求服务端数据,因为网络的读取会阻塞,所以该过程不能放在Qt中的UI主线程当中,需要用一个后台线程来读取数据,数据准备完毕后 在通过Qt5中的信号槽机制来跨线程的传递数据 ...
- Android中UI线程与后台线程交互设计的5种方法
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...
- 通过使用Web Workers,Web应用程序可以在独立于主线程的后台线程中,运行一个脚本操作。这样做的好处是可以在独立线程中执行费时的处理任务,从而允许主线程(通常是UI线程)不会因此被阻塞/放慢。
Web Workers API - Web API 接口参考 | MDNhttps://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API ...
- Qt中运行后台线程不阻塞UI线程的方案
有一个想法,一个客户端,有GUI界面的同时也要向网络服务器发送本地采集的数据,通过网络发送数据的接口是同步阻塞的,需要等待服务器响应数据. 如果不采用后台线程的方案,用主UI线程关联一个定时器QTim ...
- java中创建线程的方式
创建线程的方式: 继承thread 实现runnable 线程池 FurureTask/Callable 第一种:继承thread demo1: public class demo1 { public ...
随机推荐
- WCF Ajax Json的应用
WCF Ajax 的应用网上实际上有很多, 如: Ajax与Wcf交互-JSON jQuery调用WCF服务传递JSON对象 WCF以Json格式返回对象,客户端以JS调用显示 关于SoapUI的介绍 ...
- RV ItemDecoration 分割线 简介 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(六)针对spark2.2.1以yarn方式启动spark-shell抛出异常:ERROR cluster.YarnSchedulerBackend$YarnSchedulerEndpoint: Sending RequestExecutors(0,0,Map(),Set()) to AM was unsuccessful
Spark以yarn方式运行时抛出异常: [spark@master bin]$ cd /opt/spark--bin-hadoop2./bin [spark@master bin]$ ./spark ...
- Python在VSCode中进入交互界面调试
VSCode非常强大,断点好用,美中不足,每次只能通过下面窄窄一行进行各种检查,而python的优点就在于交互式的调试,所以希望能够在断点时能够进入到正常的交互界面进行调试. 我用的插件是: 设置交互 ...
- [Canvas]RPG游戏雏形 (地图加载,英雄出现并移动)
源码请点此下载并用浏览器打开index.html观看 图例: 代码: <!DOCTYPE html> <html lang="utf-8"> <met ...
- 微信小程序开发-滑动操作
在实际应用中,当某种手势被触发后,在用户没有放开鼠标或手指前,会一直识别为该手势.比如当用户触发左滑手势后,这时再向下滑动,仍要按照左滑手势来处理. 可以定义一个标记来记录第一次识别到的手势,如果已识 ...
- WPF编程:textbox控件文本框数据显示最后一行
WPF编程:textbox控件文本框数据显示最后一行 TextBox控件在接收大量数据的时候,滚动条一般在最上方,如何使滚动条随着数据的接收而向下滚动呢?比如有一个TextBox'控件txbRecvD ...
- JQuery为textarea添加maxlength
<html> <head> <title>JQuery为textarea添加maxlength</title> <script type=&quo ...
- Asp.Net下通过切换CSS换皮肤
直接重写Render事件 protected override void Render(System.Web.UI.HtmlTextWriter writer) { StringWriter sw = ...
- Dockerfile 指令 ADD 和 COPY介绍
一.ADD指令 ADD指令的功能是将主机构建环境(上下文)目录中的文件和目录.以及一个URL标记的文件 拷贝到镜像中. 其格式是: ADD 源路径 目标路径 如: #test FROM ubunt ...