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線程只用編寫一個槽函數來接收做完的信號並處理就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM