[Qt教程] 第32篇 网络(二)HTTP
生活随笔
收集整理的這篇文章主要介紹了
[Qt教程] 第32篇 网络(二)HTTP
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[Qt教程]?第32篇 網絡(二)HTTP
??|?查看: 637|?回復: 8| HTTP 版權聲明 該文章原創于作者yafeilinux,轉載請注明出處! 導語 ? ?? ?? HTTP(HyperText Transfer Protocol,超文本傳輸協議)是一個客戶端和服務器端請求和應答的標準。在Qt的網絡模塊中提供了網絡訪問接口來實現HTTP編程。網絡訪問接口是執行一般的網絡操作的類的集合,該接口在特定的操作和使用的協議(例如,通過HTTP進行獲取和發送數據)上提供了一個抽象層,只為外部暴露出了類、函數和信號。 上一節中我們已經提到過了,現在Qt中使用QNetworkAccessManager類和QNetworkReply類來進行HTTP的編程。網絡請求由QNetworkRequest類來表示,它也作為與請求有關的信息(例如,任何頭信息和使用加密)的容器。在創建請求對象時指定的URL決定了請求使用的協議,目前支持HTTP、FTP和本地文件URLs的上傳和下載。QNetworkAccessManager類用來協調網絡操作,每當一個請求創建后,該類用來調度它,并發射信號來報告進度。該類還協調cookies的使用,身份驗證請求,及其代理的使用等。對于網絡請求的應答使用QNetworkReply類表示,它會在請求被完成調度時由QNetworkAccessManager來創建。QNetworkReply提供的信號可以用來單獨的監視每一個應答。 ? ?? ? 下面我們先講解一個簡單下載網頁的例子,然后將其擴展為可以下載任何文件。 環境:Windows Xp + Qt 4.8.5+Qt Creator 2.8.0 目錄 一、簡單的網頁瀏覽功能 二、實現下載文件功能 正文 一、簡單的網頁瀏覽功能 1.新建Qt Gui應用,項目名稱為http,基類使用默認的QMainWindow即可,類名為MainWindow。 2.完成后打開http.pro文件,然后添加下面一行代碼來使用網絡模塊: QT??+=?network ? ?? ??然后保存該文件。 3.下面打開mainwindow.ui文件進入設計模式,向界面上添加一個Text Browser部件。效果如下圖所示。 4.打開mainwindow.h文件,先包含頭文件:#include <QtNetwork> 然后添加一個private私有對象定義:QNetworkAccessManager *manager; 最后添加一個私有槽聲明: private slots: void replyFinished(QNetworkReply *); 5.下面到mainwindow.cpp文件中,先在構造函數中添加如下代碼: manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), this,SLOT(replyFinished(QNetworkReply*))); manager->get(QNetworkRequest(QUrl("http://www.qter.org"))); 這里先創建了一個QNetworkAccessManager類的實例,它用來發送網絡請求和接收應答。然后關聯了管理器的finished()信號和我們自定義的槽,每當網絡應答結束時都會發射這個信號。最后使用了get()函數來發送一個網絡請求,網絡請求使用QNetworkRequest類表示,get()函數返回一個QNetworkReply對象。除了get()函數,管理器還提供了發送HTTP POST請求的post()函數。 6.下面添加槽的定義: void MainWindow::replyFinished(QNetworkReply *reply) { QTextCodec *codec = QTextCodec::codecForName("utf8"); QString all = codec->toUnicode(reply->readAll()); ui->textBrowser->setText(all); reply->deleteLater(); } 因為QNetworkReply繼承自QIODevice類,所以可以操作一般的I/O設備一樣來操作該類。這里使用了readAll()函數來讀取所有的應答數據,為了正常顯示中文,使用了QTextCodec類來轉換編碼。在完成數據的讀取后,需要使用deleteLater()來刪除replay對象。 7.因為這里使用了QtextCodec類,所以還需要在mainwindow.cpp文件中包含頭文件 #include <QTextCodec> ? ?? ??下面運行程序,效果如下圖所示。 ? ?? ?? 這里再將整個過程簡答敘述一遍:上面實現了最簡單的應用HTTP協議下載網頁的功能。QNetworkAccessManager類用于發送網絡請求和接受回復,具體來說,它是用QNetworkRequest?類來管理請求,QNetworkReply類進行接收回復,并對數據進行處理。 在上面的代碼中,我們使用了下面的代碼來發送請求: manager->get(QNetworkRequest(QUrl("http://www.qter.org"))); 它返回一個QNetworkReply對象,這個后面再講。我們只需知道只要發送請求成功,它就會下載數據。而當數據下載完成后,manager會發出finished()信號,我們關聯了該信號: connect(manager, SIGNAL(finished(QNetworkReply*)), this,SLOT(replyFinished(QNetworkReply*))); 也就是說,當下載數據結束時,就會執行replyFinished()函數。在這個函數中我們對接收的數據進行處理: QTextCodec *codec = QTextCodec::codecForName("utf8"); QString all = codec->toUnicode(reply->readAll()); ui->textBrowser->setText(all); 這里,為了能顯示下載的網頁中的中文,我們使用了QTextCodec?類對象,應用utf8編碼。使用reply->readAll()函數就可以將下載的所有數據讀出。然后,我們在textBrowser中將數據顯示出來。當reply對象已經完成了它的功能時,我們需要將它釋放,就是最后一條代碼: reply->deleteLater(); 二、實現下載文件功能 ? ?? ?? 通過上面的例子可以看到,Qt中編寫基于HTTP協議的程序是十分簡單的,只有十幾行代碼。不過,一般我們下載文件都想要看到下載進度。下面我們就更改上面的程序,讓它可以下載任意的文件,并且顯示下載進度。 1.進入設計模式,刪除以前的Text Browser部件,然后拖入一個Line Edit,一個Label,一個Progress Bar和一個Push Button,設計界面如下圖所示。 2.?在寫代碼之前,我們先介紹一下整個程序執行的流程:開始我們先讓進度條隱藏。當我們在Line Edit中輸入下載地址,點擊下載按鈕后,我們應用輸入的下載地址,獲得文件名,在磁盤上新建一個文件,用于保存下載的數據,然后進行鏈接,并顯示進度條。在下載過程中,我們將每次獲得的數據都寫入文件中,并更新進度條,在接收完文件后,我們重新隱藏進度條,并做一些清理工作。根據這個思路,我們開始代碼的編寫。 3.到mainwindow.h中,首先添加public函數聲明: void startRequest(QUrl?url);?//請求鏈接 然后添加幾個private變量和對象定義: QNetworkReply *reply; QUrl url;? ?//存儲網絡地址 QFile *file;??//文件指針 最后到private slots中,刪除前面的replyFinished(QNetworkReply *)槽聲明,并添加如下代碼: private slots: void on_pushButton_clicked();??//下載按鈕的單擊事件槽函數 void httpFinished();??//完成下載后的處理 void httpReadyRead();??//接收到數據時的處理 void updateDataReadProgress(qint64, qint64); //更新進度條 4.?下面到mainwindow.cpp文件中,將前面在構造函數中添加的內容刪除,然后添加如下代碼: manager = new QNetworkAccessManager(this);?? ui->progressBar->hide(); 我們在構造函數中先隱藏進度條。等開始下載時再顯示它。 5.?下面將前面程序中添加的replyFinished()函數的定義刪除,然后添加新的函數的定義。先添加網絡請求函數的實現: void MainWindow::startRequest(QUrl url) { reply = manager->get(QNetworkRequest(url)); connect(reply, SIGNAL(readyRead()),?this, SLOT(httpReadyRead())); connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(updateDataReadProgress(qint64, qint64))); connect(reply, SIGNAL(finished()),?this, SLOT(httpFinished())); } 這里使用了get()函數來發送網絡請求,然后進行了QNetworkReply對象的幾個信號和自定義槽的關聯。其中readyRead()信號繼承自QIODevice類,每當有新的數據可以讀取時,都會發射該信號;每當網絡請求的下載進度更新時都會發射downloadProgress()信號,它用來更新進度條;每當應答處理結束時,都會發射finished()信號,該信號與前面程序中QNetworkAccessManager類的finished()信號作用相同,只不過是發送者不同,參數也不同而已。下面添加幾個槽的定義。 void MainWindow::httpReadyRead() { if (file) file->write(reply->readAll()); } 這里先判斷是否創建了文件,如果是,則讀取返回的所有數據,然后寫入到文件。該文件是在后面的“下載”按鈕單擊信號槽中創建并打開的。 void MainWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes) { ui->progressBar->setMaximum(totalBytes); ui->progressBar->setValue(bytesRead); } ? ?? ??? 這里設置了一下進度條的最大值和當前值。 void MainWindow::httpFinished() { ui->progressBar->hide(); file->flush(); file->close(); reply->deleteLater(); reply = 0; delete file; file = 0; } ? ?? ??? 當完成下載后,重新隱藏進度條,然后刪除reply和file對象。下面是“下載”按鈕的單擊信號的槽: void MainWindow::on_pushButton_clicked() { url = ui->lineEdit->text(); QFileInfo info(url.path()); QString fileName(info.fileName()); if (fileName.isEmpty()) fileName = "index.html"; file = new QFile(fileName); if(!file->open(QIODevice::WriteOnly)) { qDebug() << "file open error"; delete file; file = 0; return; } startRequest(url); ui->progressBar->setValue(0); ui->progressBar->show(); } 這里使用要下載的文件名創建了本地文件,然后使用輸入的url進行了網絡請求,并顯示進度條。 6.下面運行程序,我們先輸入www.yafeilinux.com的網址,下面一個網頁。效果如下圖所示。 ? 完成后,可以嘗試輸入一個文件的下載地址,比如這里輸入了《Qt Creator快速入門》一書在百度網盤上的地址,效果如下圖所示。 7.最后,可以去項目編譯生成的文件目錄中查看下載的文件(我這里是E:\http-build-桌面-Debug),可以看到下載的文件,如下圖所示。 結語 HTTP應用的內容就講到這里,可以看到它是很容易的,也不需要大家了解太多的HTTP的原理知識。關于相關的類的其他使用,也可以查看其幫助文檔。在上面的例子中,我們只是為了講解知識,所以程序不是很完善,對于一個真正的工程,還是需要注意更多其他細節的,大家可以查看一下Qt演示程序HTTP Client的源代碼。 涉及到的源碼:??http.zip?? |
總結
以上是生活随笔為你收集整理的[Qt教程] 第32篇 网络(二)HTTP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Qt教程] 第31篇 网络(一)Qt网
- 下一篇: [Qt教程] 第33篇 网络(三)FTP