在QCoreApplication 模式下程序不能正常退出与使用QNetworkAccessManager 的问题

QCoreApplication 是QT 的命令行( 控制台 )模式的程序,一般用来写一些没有GUI 的后端程序。

在Qt Creator创建项目,默认QCoreApplication模板项目中 mian 函数最后是 return a.exec();  这实际使程序进入了消息循环。它导致你的程序在这里阻塞了不会自动结束,如果把它改成了 return 0; 则程序的执行完前面的语句后到这里就返回了(  退出 结束 )。如果我们的程序一条线执行下来当然没有问题,但是如果我们使用的某有些方法特别是多线程方法中另开了一条阻塞时,这个地方的return 0; 就会导致我们的方法等不到返回就直接退出了。

就好比我在这里发出一条消息,等待着消息返回,如果不返回我就等着,直等到消息回来了才做后面的事情。这就必须需要我们的main 中有消息循环才可以。 否则直接退出就将导致我要的消息没有回来进程就结束了。

那么如何保证的控制台程序中可以使用QNetworkAccessManager 发送与接收消息,在处理完消息后又通正常结束程序?

一般只有使用的是POST 时会遇到这个问题,GET 一般不会有....

直接上代码:


主线程:

#include <QCoreApplication>
#include "Collect.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //创建一个继承于QThread 的子线程类;要做的工作都放在这个子线程中执行
    CollectThread *collect = new CollectThread();
    
    //监听线程开启消息( 连接信号槽 );在子线程中开个工作方法work(); 不使用其默认的 run();
    collect->connect( collect, &CollectThread::started,
                      collect, &CollectThread::work );
                      
    //监听线程结束消息;如果子线程结束,则调用主线程的 quit();                  
    QObject::connect( collect,SIGNAL( finished()),
                      &a, SLOT(quit()) );
    
    
    //开启线程                  
    collect->start();
    
    
    return a.exec();
}


子线程:


class CollectThread : public QThread
{
    Q_OBJECT
    public:
        explicit CollectThread(QObject *parent = 0);
    public Q_SLOTS:
        void work();
};


CollectThread::CollectThread(QObject *parent):QThread(parent)
{

}

void CollectThread::work(){


   /**
   * 模拟 POST 请求 发送采集数据
   ==================================================================*/
  QNetworkAccessManager* manager = new QNetworkAccessManager;
  
  //要通过POST 发送JSON 数据包
  QJsonObject obj;   
  obj.insert("LicenseStatus", "1" );  
  obj.insert("WorkUnit", "0.1" );
  
  QNetworkRequest request;
  request.setUrl(QUrl( actionResult ) ); //目标地址
  
  /**
   * 构造一个模拟浏览器发起的 http 请求包
   */
  request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
  //request.setRawHeader("X-Requested-With","XMLHttpRequest");
  //request.setRawHeader("User-Agent","Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)");
  //request.setRawHeader("Accept-Encoding","gzip,deflate");
  //request.setRawHeader("Connection","Keep-Alive");
  //request.setRawHeader("Cache-Control","no-cache");

  /** POST */
  manager->post( request, QJsonDocument( obj ).toJson() );
  
  /** NetworkReply 消息处理 (异步)*/
  /** [] 中 需要有“this” ,内部方法中才可以访问外面的成员 */
  QObject::connect( manager, &QNetworkAccessManager::finished, [this](QNetworkReply* reply){

      qDebug()  << "==== 服务端返回消息 ===============================================================";

         if(reply->error() != QNetworkReply::NoError)
         {
             qDebug() << "Error:" << reply->errorString();
             this->quit();
         }

         QByteArray buf = reply->readAll();
         qDebug() << "OK:"<< buf;
       
         //线程在里结束,这里会触发主线程对finished 的监听。
         this->quit();

   });


}