利用QEventLoop實現同步等待信號槽返回結果
阿新 • • 發佈:2018-05-06
有一個 str ID 主程 col 一個 例子 就是 pid
在QT中想要實現一個簡單的函數:給定一個網頁地址(http://www.hao123.com),等待返回網頁的html內容。
當然我想到可利用QNetWork相關的類:QNetworkAccessManager、QNetworkRequest、QNetworkReply三個類;進一步深入發現,網絡訪問一般是異步的,因此Qt中reply的結果是利用信號/槽機制來進行通知和處理的,這仍然是異步的,也就是說不能立即取得reply結果,而只能在槽函數中來處理reply結果。我也想到用lambda函數實現槽函數,似乎能立即取得結果,但可惜的是lambda函數仍然是異步調用的。
所以想簡單的一個函數實現以上功能不現實。我用一個類來實現該功能。
頭文件: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 };
實現文件: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 17 WebSpider::~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); //網絡訪問結束時,結束事件循環 30 connect(_netManager, &QNetworkAccessManager::finished, this, &WebSpider::requestFinished); //網絡訪問結束時,處理返回結果 31 el->exec(); //開始事件循環,等待網絡訪問結束 32 //事件循環結束後,requestFinished槽中已獲取網絡訪問結果,保存於_replyResult中 33 return QString(_replyResult); //返回結果 34 } 35 36 void WebSpider::requestFinished(QNetworkReply *reply) 37 { 38 _replyResult=reply->readAll(); 39 }
在程序中只需要簡單二行代碼就可取得結果
1 WebSpider ws; 2 QString htmlStr=ws.getHtml("http://www.hao123.com");
就象一個函數一樣,結果立即就獲得了,沒有異步訪問的感覺了,呵呵。任務達成。
WebSpider中實際上是異步的,但利用QEventLoop等待異步調用後,再返回結果的,也就是說,有一個等待的過程。這裏我們沒有考慮網絡異常的可能,具體應用中可進一步完善。
在QT中異步無處不在,這個小例子有助於我們實現一些簡單的小功能,將異步的代碼集中包裝,在主程序中代碼將顯示出簡單直接。
利用QEventLoop實現同步等待信號槽返回結果