基於Qt的Http程式設計基本原理
基於Qt的Http程式設計基本原理
在Qt中,使用QNetworkAccessManager類就可以完成基於Http協議的資料上傳和下載,該類既可以傳送網路請求,也可以接收網路。而具體的網路請求是通過QNetworkRequest類傳送的,具體的網路是通過QNetworkReply類來接收的。
本文將利用上面的幾個類實現一個簡單的Http客戶端,從指定的網址下載資料。
基本原理
由於QNetworkAccessManager類中包含了一組標準的資料請求函式,因此可以通過該類的物件傳送資料請求函式;每個請求函式執行完畢時都回返回一個QNetworkReply物件。當所有請求的資料都到達本地後,將引發一個finished()訊號,該訊號關聯了一個處理返回資料的槽函式。具體的實現可參考下述程式碼:
01 |
Widget::Widget(QWidget *parent) : |
02 |
QWidget(parent), |
03 |
ui( new Ui::Widget) |
04 |
{ |
05 |
ui->setupUi( this ); |
06 |
07 |
manager = new QNetworkAccessManager( this ); |
08 |
connect(manager, SIGNAL(finished(QNetworkReply *)), |
09 |
this , SLOT(replyFinished(QNetworkReply*))); |
10 |
11 |
manager->get(QNetworkRequest(QUrl( |
12 |
"http://www.kerneltravel.net/" ))); |
13 |
} |
可以看到,上述的基本原理大部分都在建構函式中完成。首先建立了一個QNetworkAccessManager物件manager;接著將manager所引發的finished()訊號與replyFinished()槽進行關聯;最後通過get()傳送資料請求。
get()用於傳送請求並獲得目標地址中的資料,具體的資料請求則是通過建立一個QNetworkRequest類的物件而完成的。只要資料請求傳送成功,則開始下載資料。當所有的資料下載完成後,就返回一個QNetworkReply型別的物件。同時manager物件將傳送一個finished()訊號,引發replyFinished槽函式的執行。
當執行上述的槽函式時,就說明目標地址的資料已經下載完畢。此時槽函式要做的就是將這些資料顯示出來。這裡我們只只對文字資料進行轉換。對這些資料的轉換動作可參考下述的程式碼:
1 |
void Widget::replyFinished(QNetworkReply *reply) |
2 |
{ |
3 |
QTextCodec *codec = QTextCodec::codecForName( "utf8" ); |
4 |
5 |
QString all = codec->toUnicode(reply->readAll()); |
6 |
ui->textEdit->setText(all); |
7 |
reply->deleteLater(); |
8 |
} |
為了能夠正確顯示中文,我們建立QTextCodec物件。利用readAll函式可以讀取資料請求返回的所有資料,並且利用toUnicode函式將這些資料轉換成QString型別。最後在使用者介面中的文字編輯器中顯示出來。
按照上面的方法就可以下載指定地址的資料。如下圖:
當返回的資料顯示完畢後,利用deleteLater函式將返回的資料刪除。
上述的執行過程用資料流圖表示如下:
上述內容只是對基於Http協議的資料下載做了簡單的描述,並沒有對介面設計作過多的介紹,關於介面的設計可見參考1。下文將對這個基本的Http客戶端進行改造。