zoukankan      html  css  js  c++  java
  • Qt5中创建临时的后台线程。

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

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

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

     1 #include <QObject>
     2 #include <QStringList>
     3 
     4 class ZipUpdatePackageTask : public QObject
     5 {
     6     Q_OBJECT
     7 
     8 public:
     9     ZipUpdatePackageTask();
    10     ~ZipUpdatePackageTask();
    11 
    12 public slots:
    13     void doZip();
    14     void beZipFiles(const QStringList& files);
    15 signals:
    16     void zipFinished();
    17     void zipPackageInfo(const QString& fileName, const QString& md5, const QString& size);
    18 
    19 private:
    20     bool beZipFilesIsEmpty();
    21     void deleteHistoryZip(const QString& targetPackage);
    22     void toBeZipFilesArguments(QString &files);
    23     void startZipTask(QString zipExePath, QString targetPackage, QString files);
    24     QString getFileMD5(const QString& targetZipPackage);
    25     QString getFileSize(const QString& targetZipPackage);
    26 private:
    27     QStringList m_files;
    28 };

    压缩任务类的 cpp文件:

      1 #include <QCoreApplication>
      2 #include <QFile>
      3 #include <QFileInfo>
      4 #include <QDir>
      5 #include <QProcess>
      6 #include <QCryptographicHash>
      7 
      8 ZipUpdatePackageTask::ZipUpdatePackageTask()
      9 {
     10 }
     11 
     12 ZipUpdatePackageTask::~ZipUpdatePackageTask()
     13 {
     14 }
     15 
     16 void ZipUpdatePackageTask::doZip()
     17 {
     18     QString appDir = qApp->applicationDirPath();
     19     QString zipExePath = QString("%1/%2").arg(appDir).arg("zip.exe");
     20     if (QFile::exists(zipExePath) && !beZipFilesIsEmpty())
     21     {
     22 
     23         QString targetZipPackage = QString("%1/%2").arg(appDir).arg("update.zip");
     24         QString beZipFiles;
     25 
     26         toBeZipFilesArguments(beZipFiles);
     27         deleteHistoryZip(targetZipPackage);
     28         startZipTask(zipExePath, targetZipPackage, beZipFiles);
     29 
     30 
     31         if (QFile::exists(targetZipPackage))
     32         {
     33             QString size = getFileSize(targetZipPackage);
     34             QString md5 = getFileMD5(targetZipPackage);
     35 
     36             emit zipPackageInfo(targetZipPackage, md5, size);
     37 
     38         }
     39 
     40 
     41     }
     42 
     43     emit zipFinished();
     44 }
     45 
     46 void ZipUpdatePackageTask::beZipFiles(const QStringList& files)
     47 {
     48     m_files.clear();
     49     m_files = files;
     50 }
     51 
     52 bool ZipUpdatePackageTask::beZipFilesIsEmpty()
     53 {
     54     return m_files.isEmpty();
     55 }
     56 
     57 void ZipUpdatePackageTask::deleteHistoryZip(const QString& targetPackage)
     58 {
     59     if (QFile::exists(targetPackage))
     60     {
     61         QDir dir;
     62         dir.remove(targetPackage);
     63     }
     64 }
     65 
     66 void ZipUpdatePackageTask::toBeZipFilesArguments(QString &files)
     67 {
     68     for (auto file : m_files)
     69     {
     70         files.append(file);
     71         files.append(" ");
     72     }
     73 }
     74 
     75 void ZipUpdatePackageTask::startZipTask(QString zipExePath, QString targetPackage, QString files)
     76 {
     77     QProcess* zipProcesss = new QProcess;
     78     //zip a [zip_package_path_name] [file1Path]...[fileNPath]
     79     QString command = QString("%1 a %2 %3").arg(zipExePath).arg(targetPackage).arg(files);
     80     zipProcesss->start(command);
     81     zipProcesss->waitForFinished(-1);
     82 }
     83 
     84 QString ZipUpdatePackageTask::getFileMD5(const QString& targetZipPackage)
     85 {
     86     QString md5;
     87     QFile file(targetZipPackage);
     88     if (file.open(QFile::ReadOnly))
     89     {
     90         QCryptographicHash hash(QCryptographicHash::Md5);
     91         if (hash.addData(&file))
     92         {
     93             md5 = QString(hash.result().toHex());
     94         }
     95 
     96         file.close();
     97     }
     98     return md5;
     99 }
    100 
    101 QString ZipUpdatePackageTask::getFileSize(const QString& targetZipPackage)
    102 {
    103     QFileInfo fileInf(targetZipPackage);
    104     return QString::number(fileInf.size());
    105 }

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

     1 void StatisticsWidget::slotUploadPackage()
     2 {
     3     QThread *zipThread = new QThread;
     4     ZipUpdatePackageTask* task = new ZipUpdatePackageTask();
     5 
     6 
     7     QStringList beZipFiles;
     8     for (int listRow = 0; listRow < ui->updateFileList->count(); ++listRow)
     9     {
    10         beZipFiles << ui->updateFileList->item(listRow)->text();
    11     }
    12 
    13     task->beZipFiles(beZipFiles);
    14     task->moveToThread(zipThread);
    15 
    16     connect(zipThread, &QThread::started, task, &ZipUpdatePackageTask::doZip);
    17 
    18     connect(task, SIGNAL(zipFinished()), zipThread, SLOT(quit()));
    19     connect(task, &ZipUpdatePackageTask::zipPackageInfo, this, &StatisticsWidget::slotZipFinished,Qt::QueuedConnection);
    20 
    21     //automatically delete thread and task object when work is done:
    22     connect(zipThread, SIGNAL(finished()), task, SLOT(deleteLater()));
    23     connect(zipThread, SIGNAL(finished()), zipThread, SLOT(deleteLater()));
    24     zipThread->start();
    25 }

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

  • 相关阅读:
    Python3 面向对象小练习
    Python3 面向对象进阶1
    Python3 类的继承小练习
    Python3 类的继承
    Python3 数据结构之词频统计(英文)
    Python3 类与对象之王者荣耀对战小游戏
    Python3 类与对象
    SQL优化单表案例
    SQL性能分析
    索引简介
  • 原文地址:https://www.cnblogs.com/foohack/p/7615100.html
Copyright © 2011-2022 走看看