Using QEventLoop to synchronously wait for the return result of the signal slot

I want to implement a simple function in QT: given a web page address (http://www.hao123.com), wait for the html content of the returned web page.

Of course, I thought of using QNetWork-related classes: QNetworkAccessManager, QNetworkRequest, QNetworkReply; further in-depth discovery, network access is generally asynchronous, so the result of reply in Qt is to use the signal/slot mechanism for notification and processing, which It is still asynchronous, that is to say, the reply result cannot be obtained immediately, but the reply result can only be processed in the slot function. I also thought of implementing the slot function with a lambda function, which seems to get the result immediately, but unfortunately the lambda function is still called asynchronously.

Therefore, it is unrealistic to think of a simple function to achieve the above functions. I use a class to implement this functionality.

Header file: webspider.h

 1 #include "QtNetwork\QNetworkAccessManager"
 2 class WebSpider:public QObject
 3 {
 4     Q_OBJECT    
 5 public:
 6     WebSpider();
 7     ~WebSpider();
 8 
 9     QString getHtml(QString urlStr);
10 
11 public slots:
12     void requestFinished(QNetworkReply *reply);
13 private:
14     QNetworkAccessManager* _netManager;
15     QNetworkRequest* _netRequest;
16     
17     QByteArray _replyResult;
18 };

Implementation file: webspider.cpp

 1 #include "WebSpider.h"
 2 #include "QEventLoop"
 3 #include "QtNetwork\QNetworkAccessManager"
 4 #include "QtNetwork\QNetworkReply"
 5 #include "QObject"
 6 
 7 
 8 
 9 WebSpider::WebSpider()
10     :QObject()
11 {
12     _netManager = new QNetworkAccessManager();
13     
14 }
15 
16 
17WebSpider::~ WebSpider()
 18  {
 19      delete _netManager;
 20  }
 21  
22  QString WebSpider::getHtml(QString urlStr)
 23  {
 24      _netRequest = new QNetworkRequest(QUrl(urlStr));
 25      _netManager-> get (* _netRequest);
 26      
27      QEventLoop* el = new QEventLoop();
 28  
29      connect(_netManager, &QNetworkAccessManager::finished, el, &QEventLoop::quit);     // When the network access ends, end the event loop 
30     connect(_netManager, &QNetworkAccessManager::finished, this , &WebSpider::requestFinished); // When the network access ends, the processing returns the result 
31      el->exec();     // Start the event loop, wait for the end of the network access
 32      // Event loop After the end, the network access result has been obtained in the requestFinished slot and stored in _replyResult 
33      return QString(_replyResult);     // return result 
34  }
 35  
36  void WebSpider::requestFinished(QNetworkReply * reply)
 37  {
 38      _replyResult=reply-> readAll();
 39 }

The result can be obtained with only two simple lines of code in the program

1 WebSpider ws;
2 QString htmlStr=ws.getHtml("http://www.hao123.com");

Just like a function, the result is obtained immediately, there is no sense of asynchronous access, huh, huh. Mission accomplished.
WebSpider is actually asynchronous, but after using QEventLoop to wait for an asynchronous call, the result is returned, that is, there is a waiting process. Here we do not consider the possibility of network anomalies, which can be further improved in specific applications.

Asynchrony is everywhere in QT. This small example helps us to implement some simple functions, wrap the asynchronous code centrally, and the code in the main program will be simple and direct.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325458017&siteId=291194637