C++?Qt開發(fā)之使用QNetworkAccessManager實現(xiàn)Web網(wǎng)頁訪問
Qt 是一個跨平臺C++圖形界面開發(fā)庫,利用Qt可以快速開發(fā)跨平臺窗體應用程序,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現(xiàn)圖形化開發(fā)極大的方便了開發(fā)效率,本章將重點介紹如何運用QNetworkAccessManager組件實現(xiàn)Web網(wǎng)頁訪問。
QNetworkAccessManager是Qt網(wǎng)絡模塊中的關(guān)鍵類,用于管理網(wǎng)絡訪問和請求。作為一個網(wǎng)絡請求的調(diào)度中心,它為Qt應用程序提供了發(fā)送和接收各種類型的網(wǎng)絡請求的能力,包括常見的GET、POST、PUT、DELETE等。這個模塊的核心功能在于通過處理QNetworkReply和QNetworkRequest來實現(xiàn)與網(wǎng)絡資源的交互。
通過QNetworkAccessManager,Qt應用程序能夠輕松地與遠程服務器通信,獲取數(shù)據(jù)或?qū)?shù)據(jù)上傳到服務器。這種網(wǎng)絡請求的管理不僅是異步的,以確保不會阻塞主線程,還提供了豐富的信號和槽機制,使得開發(fā)者可以靈活地處理不同階段的網(wǎng)絡操作。
通常,QNetworkAccessManager會與QNetworkReply和QNetworkRequest一起使用。QNetworkRequest用于封裝和配置網(wǎng)絡請求的各種屬性,例如URL、請求頭等。而QNetworkReply則代表了對網(wǎng)絡請求的響應,包含了請求返回的數(shù)據(jù)和相關(guān)信息。這三者共同協(xié)作,為Qt應用程序提供了便捷、靈活且強大的網(wǎng)絡通信能力。
1.通用API函數(shù)
1.1QNetworkAccessManager
要想實現(xiàn)網(wǎng)絡通信首先需要新建一個網(wǎng)絡訪問管理器,以下是QNetworkAccessManager類中的一些常用函數(shù)及其描述:
| 函數(shù) | 描述 |
|---|---|
| QNetworkAccessManager(QObject *parent = nullptr) | 構(gòu)造函數(shù),創(chuàng)建一個QNetworkAccessManager實例。 |
| virtual ~QNetworkAccessManager() | 虛析構(gòu)函數(shù),釋放QNetworkAccessManager實例。 |
| QNetworkReply *get(const QNetworkRequest &request) | 發(fā)送GET請求,并返回與請求關(guān)聯(lián)的QNetworkReply對象。 |
| QNetworkReply *post(const QNetworkRequest &request, QIODevice *data) | 發(fā)送POST請求,并返回與請求關(guān)聯(lián)的QNetworkReply對象。 |
| QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data) | 發(fā)送POST請求,并返回與請求關(guān)聯(lián)的QNetworkReply對象。 |
| QNetworkReply *put(const QNetworkRequest &request, QIODevice *data) | 發(fā)送PUT請求,并返回與請求關(guān)聯(lián)的QNetworkReply對象。 |
| QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data) | 發(fā)送PUT請求,并返回與請求關(guān)聯(lián)的QNetworkReply對象。 |
| QNetworkReply *deleteResource(const QNetworkRequest &request) | 發(fā)送DELETE請求,并返回與請求關(guān)聯(lián)的QNetworkReply對象。 |
| QNetworkReply *head(const QNetworkRequest &request) | 發(fā)送HEAD請求,并返回與請求關(guān)聯(lián)的QNetworkReply對象。 |
| QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = nullptr) | 發(fā)送自定義請求,并返回與請求關(guān)聯(lián)的QNetworkReply對象。 |
| QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, const QByteArray &data) | 發(fā)送自定義請求,并返回與請求關(guān)聯(lián)的QNetworkReply對象。 |
| void setConfiguration(const QNetworkConfiguration &config) | 設置網(wǎng)絡配置,用于定制網(wǎng)絡行為。 |
| QNetworkConfiguration configuration() const | 獲取當前網(wǎng)絡配置。 |
| void clearAccessCache() | 清除網(wǎng)絡訪問緩存。 |
| void setCache(QAbstractNetworkCache *cache) | 設置網(wǎng)絡緩存。 |
| QAbstractNetworkCache *cache() const | 獲取當前網(wǎng)絡緩存。 |
| void setCookieJar(QNetworkCookieJar *cookieJar) | 設置用于管理HTTP cookie的QNetworkCookieJar。 |
| QNetworkCookieJar *cookieJar() const | 獲取當前的HTTP cookie管理器。 |
這些函數(shù)提供了QNetworkAccessManager的核心功能,使得開發(fā)者能夠方便地進行各種類型的網(wǎng)絡請求,配置網(wǎng)絡參數(shù),并進行相關(guān)的網(wǎng)絡管理操作。
1.2QNetworkReply
以下是QNetworkReply類中的一些常用函數(shù)及其描述:
| 函數(shù) | 描述 |
|---|---|
| QByteArray readAll() const | 讀取所有可用的數(shù)據(jù),并返回一個QByteArray,包含從網(wǎng)絡回復讀取的所有內(nèi)容。 |
| QByteArray peek(int maxSize) const | 查看最多maxSize字節(jié)的可用數(shù)據(jù),但不從緩沖區(qū)中移除。 |
| QByteArray read(int maxSize) | 從網(wǎng)絡回復中讀取最多maxSize字節(jié)的數(shù)據(jù),并將其從緩沖區(qū)中移除。 |
| QByteArray readLine(int maxSize = 0) | 從網(wǎng)絡回復中讀取一行數(shù)據(jù),最多包含maxSize字節(jié),并將其從緩沖區(qū)中移除。 |
| void ignoreSslErrors(const QList<QSslError> &errors = QList<QSslError>()) | 忽略SSL錯誤,繼續(xù)處理網(wǎng)絡回復。 |
| void abort() | 終止網(wǎng)絡回復的處理,關(guān)閉底層連接。 |
| void close() | 關(guān)閉網(wǎng)絡回復的處理。 |
| QUrl url() const | 返回與網(wǎng)絡回復相關(guān)聯(lián)的URL。 |
| QNetworkRequest request() const | 返回生成此網(wǎng)絡回復的網(wǎng)絡請求。 |
| QNetworkAccessManager *manager() const | 返回與網(wǎng)絡回復相關(guān)聯(lián)的QNetworkAccessManager。 |
| bool isFinished() const | 檢查網(wǎng)絡回復是否已完成。 |
| QNetworkReply::NetworkError error() const | 返回網(wǎng)絡回復的錯誤代碼。 |
| bool hasRawHeader(const QByteArray &headerName) const | 檢查網(wǎng)絡回復是否包含指定原始頭。 |
| QList<QByteArray> rawHeaderList() const | 返回網(wǎng)絡回復的所有原始頭的列表。 |
| QByteArray rawHeader(const QByteArray &headerName) const | 返回指定原始頭的值。 |
| QVariant header(QNetworkRequest::KnownHeaders header) const | 返回指定標準頭的值。 |
| QList<QByteArray> rawHeaderValues(const QByteArray &headerName) const | 返回指定原始頭的所有值。 |
| QVariant attribute(QNetworkRequest::Attribute code) const | 返回指定網(wǎng)絡請求屬性的值。 |
| QIODevice *readAllStandardOutput() | 讀取標準輸出的所有數(shù)據(jù),并返回一個QIODevice,用于訪問讀取的內(nèi)容。 |
| QIODevice *readAllStandardError() | 讀取標準錯誤的所有數(shù)據(jù),并返回一個QIODevice,用于訪問讀取的內(nèi)容。 |
| bool isReadable() const | 檢查網(wǎng)絡回復是否可讀取。 |
這些函數(shù)提供了對QNetworkReply實例進行各種操作和查詢的方法,包括讀取回復數(shù)據(jù)、處理SSL錯誤、獲取請求信息、檢查錯誤狀態(tài)等。開發(fā)者可以根據(jù)具體需求使用這些函數(shù)來有效地與網(wǎng)絡回復進行交互。
1.3QNetworkRequest
以下是QNetworkRequest類中的一些常用函數(shù)及其描述:
| 函數(shù) | 描述 |
|---|---|
| QNetworkRequest(const QUrl &url) | 使用給定的URL構(gòu)造一個QNetworkRequest實例。 |
| void setUrl(const QUrl &url) | 設置QNetworkRequest的URL。 |
| QUrl url() const | 返回與QNetworkRequest相關(guān)聯(lián)的URL。 |
| void setRawHeader(const QByteArray &headerName, const QByteArray &headerValue) | 設置指定原始頭的值。 |
| QByteArray rawHeader(const QByteArray &headerName) const | 返回指定原始頭的值。 |
| bool hasRawHeader(const QByteArray &headerName) const | 檢查QNetworkRequest是否包含指定原始頭。 |
| void setRawHeaderList(const QList<QByteArray> &headerList) | 設置所有原始頭的列表。 |
| QList<QByteArray> rawHeaderList() const | 返回QNetworkRequest的所有原始頭的列表。 |
| void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value) | 設置指定標準頭的值。 |
| QVariant header(QNetworkRequest::KnownHeaders header) const | 返回指定標準頭的值。 |
| void setAttribute(QNetworkRequest::Attribute code, const QVariant &value) | 設置指定網(wǎng)絡請求屬性的值。 |
| QVariant attribute(QNetworkRequest::Attribute code) const | 返回指定網(wǎng)絡請求屬性的值。 |
| void setSslConfiguration(const QSslConfiguration &config) | 設置SSL配置。 |
| QSslConfiguration sslConfiguration() const | 返回SSL配置。 |
| void setMaximumRedirectsAllowed(int maxRedirects) | 設置允許的最大重定向次數(shù)。 |
| int maximumRedirectsAllowed() const | 返回允許的最大重定向次數(shù)。 |
| void setOriginatingObject(QObject *object) | 設置發(fā)起此網(wǎng)絡請求的對象。 |
| QObject *originatingObject() const | 返回發(fā)起此網(wǎng)絡請求的對象。 |
| bool isEmpty() const | 檢查QNetworkRequest是否為空(未設置URL)。 |
這些函數(shù)提供了對QNetworkRequest實例進行各種操作和查詢的方法,包括設置和獲取頭信息、設置SSL配置、設置和獲取網(wǎng)絡請求屬性等。開發(fā)者可以根據(jù)具體需求使用這些函數(shù)來有效地構(gòu)建和管理網(wǎng)絡請求。
2.實現(xiàn)Web頁面訪問
要使用該模塊讀者應該在*.pro文件內(nèi)包含network網(wǎng)絡模塊,并在頭文件中引入QNetworkAccessManager、QNetworkReply、QNetworkRequest三個類,在建立訪問時首先使用QNetworkAccessManager新增一個manager管理類,并通過QNetworkRequest類創(chuàng)建一個GET請求地址,通過使用manager.get方法實現(xiàn)對特定頁面的訪問。
當訪問完成時需要通過一個信號來實現(xiàn)對數(shù)據(jù)的處理,在QNetworkReply類中包含有如下表所示的信號以供讀者使用,例如當訪問被完成時則自動觸發(fā)&QNetworkReply::finished完成信號,此時只需要對該信號進行相應的處理即可,通常會使用一個槽函數(shù)來處理它。
| 信號 | 描述 |
|---|---|
| finished() | 當網(wǎng)絡請求完成時發(fā)出。 |
| downloadProgress(qint64, qint64) | 在下載過程中定期發(fā)出,提供下載進度信息。參數(shù)為已下載的字節(jié)數(shù)和總字節(jié)數(shù)。 |
| uploadProgress(qint64, qint64) | 在上傳過程中定期發(fā)出,提供上傳進度信息。參數(shù)為已上傳的字節(jié)數(shù)和總字節(jié)數(shù)。 |
| readyRead() | 當有可讀取的數(shù)據(jù)時發(fā)出,用于通知應用程序可以調(diào)用readAll()或read()方法以獲取更多數(shù)據(jù)。 |
| error(QNetworkReply::NetworkError) | 當網(wǎng)絡請求發(fā)生錯誤時發(fā)出,參數(shù)為錯誤代碼。 |
| sslErrors(const QList<QSslError> &) | 當SSL錯誤發(fā)生時發(fā)出,參數(shù)為SSL錯誤的列表。 |
這些信號提供了豐富的信息,使開發(fā)者能夠在不同階段處理網(wǎng)絡請求。同理,在下載和上傳過程中可以使用downloadProgress和uploadProgress信號來獲取進度信息,readyRead信號表示有可讀取的數(shù)據(jù),error信號表示請求發(fā)生錯誤,sslErrors信號表示SSL相關(guān)的錯誤。
當信號被觸發(fā)時則會通過QObject::connect連接到對應的槽函數(shù)上,如下案例中所示,在槽函數(shù)內(nèi)通過reply->attribute方法我們獲取到此次響應碼中的QNetworkRequest::HttpStatusCodeAttribute屬性,該屬性用來指明本次訪問的狀態(tài)值。此類屬性也有許多可供參考,如下所示;
| 屬性 | 描述 |
|---|---|
| QNetworkRequest::HttpStatusCodeAttribute | HTTP響應的狀態(tài)碼。 |
| QNetworkRequest::HttpReasonPhraseAttribute | HTTP響應的原因短語,如"OK"、"Not Found"等。 |
| QNetworkRequest::RedirectionTargetAttribute | 重定向目標的URL。 |
| QNetworkRequest::ConnectionEncryptedAttribute | 連接是否加密的標志,返回一個bool值。 |
| QNetworkRequest::SourceIsFromCacheAttribute | 請求是否來自緩存的標志,返回一個bool值。 |
| QNetworkRequest::HttpPipeliningAllowedAttribute | 是否允許HTTP流水線傳輸?shù)臉酥?,返回一個bool值。 |
| QNetworkRequest::HttpPipeliningWasUsedAttribute | 是否使用了HTTP流水線傳輸?shù)臉酥?,返回一個bool值。 |
| QNetworkRequest::CustomVerbAttribute | 自定義請求動作(HTTP verb)的字符串。 |
| QNetworkRequest::User | 用戶自定義的屬性,用于存儲任意類型的用戶數(shù)據(jù)。 |
這些屬性提供了額外的信息,使得開發(fā)者能夠更全面地了解和處理網(wǎng)絡響應。根據(jù)具體的應用需求,開發(fā)者可以選擇使用這些屬性中的一個或多個來獲取所需的信息。
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 創(chuàng)建網(wǎng)絡訪問管理器
QNetworkAccessManager manager;
// 創(chuàng)建GET請求
QNetworkRequest request(QUrl("http://www.baidu.com"));
// 發(fā)送GET請求
QNetworkReply *reply = manager.get(request);
// 連接信號槽,處理響應
QObject::connect(reply, &QNetworkReply::finished, [&]()
{
if (reply->error() == QNetworkReply::NoError)
{
// 獲取請求的 URL
qDebug() << "Request URL:" << reply->request().url();
// 輸出請求頭信息
qDebug() << "Request Headers:";
QList<QByteArray> requestHeaders = reply->request().rawHeaderList();
foreach (const QByteArray &header, requestHeaders) {
qDebug() << header << ":" << reply->request().rawHeader(header);
}
// 獲取響應碼
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug() << "HttpStatusCodeAttribute:" << statusCode;
// 連接是否加密的標志
bool connectionEncryptedAttribute = reply->attribute(QNetworkRequest::ConnectionEncryptedAttribute).toBool();
qDebug() << "ConnectionEncryptedAttribute:" << connectionEncryptedAttribute;
// 請求是否來自緩存的標志
bool sourceIsFromCacheAttribute = reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
qDebug() << "SourceIsFromCacheAttribute:" << sourceIsFromCacheAttribute;
// HTTP請求是否被允許進行流水線處理的標志
bool httpPipeliningAllowedAttribute = reply->attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool();
qDebug() << "HttpPipeliningAllowedAttribute:" << httpPipeliningAllowedAttribute;
// 輸出響應頭信息
qDebug() << "Response Headers:";
QList<QByteArray> responseHeaders = reply->rawHeaderList();
foreach (const QByteArray &header, responseHeaders) {
qDebug() << header << ":" << reply->rawHeader(header);
}
// 處理響應內(nèi)容,這里可以使用 readAll() 方法獲取響應內(nèi)容
// qDebug() << "Response Content:" << reply->readAll();
} else
{
qDebug() << "Error:" << reply->errorString();
}
// 釋放資源
reply->deleteLater();
QCoreApplication::quit();
});
return a.exec();
}
讀者可自行編譯并運行這段代碼,觀察請求與相應數(shù)據(jù)如下圖所示;

至于如何在圖形界面中使用則就更簡單了,首先我們在mainwindow.h頭文件中定義好所需要的兩個槽函數(shù),函數(shù)on_finished()用于在完成請求后被調(diào)用,函數(shù)on_readyRead()則用于在回調(diào)被執(zhí)行后調(diào)用,并并以兩個網(wǎng)絡管理類的指針變量,如下所示;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
//自定義槽函數(shù)
void on_finished();
void on_readyRead();
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
QNetworkAccessManager networkManager; // 網(wǎng)絡管理
QNetworkReply *reply; // 網(wǎng)絡響應
};
當獲取按鈕被點擊后則開始執(zhí)行讀入指定URL地址,并對該地址進行網(wǎng)頁訪問,同時綁定這兩個信號,一旦被觸發(fā)則自動路由到對應的槽函數(shù)上面去,如下所示;
void MainWindow::on_pushButton_clicked()
{
// 讀入URL地址
QString urlSpec = ui->lineEdit->text().trimmed();
if (urlSpec.isEmpty())
{
QMessageBox::information(this, "錯誤", "請指定URL");
return;
}
// 格式化URL
QUrl newUrl = QUrl::fromUserInput(urlSpec);
if (!newUrl.isValid())
{
QMessageBox::information(this, "錯誤", QString("無效URL: %1").arg(urlSpec));
return;
}
// 訪問頁面
reply = networkManager.get(QNetworkRequest(newUrl));
// 完成時的槽函數(shù)綁定
connect(reply, SIGNAL(finished()), this, SLOT(on_finished()));
// 讀入數(shù)據(jù)的槽函數(shù)綁定
connect(reply, SIGNAL(readyRead()), this, SLOT(on_readyRead()));
}
相對應的,在on_finished()槽函數(shù)中我們將響應頭讀出并輸出到文本框中,在on_readyRead()槽函數(shù)中則是對整個網(wǎng)站頁面源代碼的輸出功能,完整代碼如下所示;
void MainWindow::on_finished()
{
// 獲取響應碼
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if(statusCode == 200)
{
ui->plainTextEdit_2->appendPlainText("響應頭數(shù)據(jù):");
// 輸出響應頭信息
QList<QByteArray> responseHeaders = reply->rawHeaderList();
foreach (const QByteArray &header, responseHeaders)
{
ui->plainTextEdit_2->appendPlainText(header + " : " + reply->rawHeader(header));
}
}
}
// 讀入頁面源代碼
void MainWindow::on_readyRead()
{
ui->plainTextEdit->setPlainText(reply->readAll());
}
運行代碼,讀者可自行輸入特定的網(wǎng)站進行讀取測試,如下所示(完整代碼請參考課件部分);

以上就是C++ Qt開發(fā)之使用QNetworkAccessManager實現(xiàn)Web網(wǎng)頁訪問的詳細內(nèi)容,更多關(guān)于Qt QNetworkAccessManager的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
數(shù)據(jù)結(jié)構(gòu) 數(shù)組順序存儲詳細介紹
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu) 數(shù)組順序存儲詳細介紹的相關(guān)資料,需要的朋友可以參考下2017-05-05
Android App仿微信界面切換時Tab圖標變色效果的制作方法
這篇文章主要介紹了Android App仿微信界面切換時Tab圖標變色效果的制作方法,重點講解了圖標的繪制技巧,需要的朋友可以參考下2016-04-04
C/C++實現(xiàn)發(fā)送與接收HTTP/S請求的示例代碼
HTTP(Hypertext Transfer Protocol)是一種用于傳輸超文本的協(xié)議,它是一種無狀態(tài)的、應用層的協(xié)議,用于在計算機之間傳輸超文本文檔,通常在 Web 瀏覽器和 Web 服務器之間進行數(shù)據(jù)通信,本文給大家介紹了C/C++發(fā)送與接收HTTP/S請求,需要的朋友可以參考下2023-11-11

