Qt6 C++ 网络请求实例

实用概念

QNetworkAccessManager是 Qt 网络模块提供的一个用于发送网络请求和接收网络响应的类。它是一个高层次的网络 API,提供了一种方便的方式来发送和接收 HTTP、FTP 和其他网络协议的数据。QNetworkAccessManager的主要功能包括:

  1. 发送网络请求:QNetworkAccessManager提供了多种发送网络请求的方法,包括get()put()post()deleteResource()等。

  2. 接收网络响应:QNetworkAccessManager可以异步接收网络响应,并在响应到达时发出信号。

  3. 处理网络错误:QNetworkAccessManager可以处理网络错误,例如连接超时、网络不可用等。

  4. 处理网络代理:QNetworkAccessManager可以使用网络代理来发送和接收网络请求。

使用QNetworkAccessManager时,通常需要创建一个QNetworkRequest对象来描述网络请求的 URL、HTTP 头、请求方法等信息,并将其传递给QNetworkAccessManager的发送请求方法中。

使用QNetworkAccessManager时,可以通过连接QNetworkAccessManager的信号,例如finished()sslErrors(),来处理网络响应和错误。在接收到网络响应时,可以使用QNetworkReply类来访问响应的 HTTP 头、数据和状态码等信息。


QNetworkReply是 Qt 网络模块提供的一个用于处理网络响应的类。它提供了访问响应 HTTP 头、数据和状态码等信息的方法,并通过信号和槽机制提供了响应处理的异步方式。

QNetworkReply的主要功能包括:

  1. 接收网络响应:QNetworkReply可以异步接收网络响应,并在响应到达时发出信号。

  2. 访问响应数据:QNetworkReply提供了多种方法来访问响应数据,例如read()readAll()bytesAvailable()等。

  3. 访问响应 HTTP 头:QNetworkReply提供了多种方法来访问响应的 HTTP 头信息,例如header()hasRawHeader()rawHeaderList()等。

  4. 访问响应状态码:QNetworkReply提供了方法来访问响应的状态码。

使用QNetworkReply时,通常需要连接QNetworkReply的信号,例如readyRead()finished(),来处理响应数据和完成响应处理。在处理响应数据时,可以使用QIODevice的读取函数来读取数据。在响应处理完成后,需要调用QNetworkReplydeleteLater()方法来释放资源。

需要注意的是,由于网络请求和响应的处理是异步的,所以在处理响应时需要注意线程安全和对象生命周期等问题。


接口请求完整步骤

pro 注册

再开始之前,我们需要在项目的 pro 文件内添加网络库

QT += core gui network


配置头文件

此处我们需要请求一个天气接口,该接口免费且无需 token 直接使用

天气接口 API: http://t.weather.itboy.net/api/weather/city/101010100
(接口 URL 最末尾的一串数字为城市代码,大家可以上网搜,我这给出的代码是北京的代码)


需要在头文件内定义一些关键性的内容

代码清单 MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMessageBox>

// 导入必备的两个网络操作库
#include <QNetworkAccessManager>
#include <QNetworkReply>

QT_BEGIN_NAMESPACE
namespace Ui {
    
     class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    
    
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

protected:
    // 获取指定城市代码天气信息的函数
    void getWeatherInfo(QString cityCode);

private:
    // 当接收到接口传回的响应时,对应的处理函数
    void onReplied(QNetworkReply *reply);

private:
    // 网络操作对象,用于执行GET或者PUT等基本网络请求
    QNetworkAccessManager *networkManager;
};
#endif // MAINWINDOW_H


主体文件

接下来的代码均写在 mainwindow.cpp 里面去

首先应当在构造函数内执行网络管理对象的初始化

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    
    
    ui->setupUi(this);

    // 实例化网络管理对象
    networkManager = new QNetworkAccessManager(this);

    // 配置当接收响应时(QNetworkAccessManager::finished),触发的回调函数onReplied
    connect(networkManager,&QNetworkAccessManager::finished,this,&MainWindow::onReplied);

    // 设置我们需要获取的天气的城市代码
    getWeatherInfo("101010100");
}

看一下获取城市天气信息函数的实现

void MainWindow::getWeatherInfo(QString cityCode)
{
    
    
    // 配置接口API
    QUrl url("http://t.weather.itboy.net/api/weather/city/"+cityCode);
    // 直接使用GET请求
    networkManager->get(QNetworkRequest(url));
}

对应的响应回调函数的实现

void MainWindow::onReplied(QNetworkReply *reply)
{
    
    
    qDebug() << "请求成功!!!"; // 输出请求成功的信息

    int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); // 获取响应状态码

    qDebug() << "状态码:" << statusCode; // 输出状态码
    qDebug() << "URL:" << reply->url(); // 输出请求的URL
    qDebug() << "操作:" << reply->operation(); // 输出操作类型
    qDebug() << "原始头信息:" << reply->rawHeaderList(); // 输出原始头信息

    if(reply->error()!=QNetworkReply::NoError||statusCode!=200){
    
     // 如果响应出现错误或状态码不为200
        qDebug() << reply->errorString().toLatin1().data(); // 输出错误信息
        QMessageBox::critical(this,"错误","无法请求接口,请检查网络是否连接正确",QMessageBox::Ok); // 弹出错误提示框
    }else{
    
     // 如果响应正常
        QByteArray buff = reply->readAll(); // 读取响应数据
        qDebug() << buff.data(); // 输出响应数据
    }

    reply->deleteLater(); // 释放reply对象
}

此时运行程序,就会发现我们成功的请求了接口,并且获取到了对应数据

下面展示的即为接口回馈的 JSON 信息

{
    
    
	"message": "success感谢又拍云(upyun.com)提供CDN赞助",
	"status": 200,
	"date": "20230710",
	"time": "2023-07-10 07:42:05",
	"cityInfo": {
    
    
		"city": "北京市",
		"citykey": "101010100",
		"parent": "北京",
		"updateTime": "07:31"
	},
	"data": {
    
    
		"shidu": "53%",
		"pm25": 12.0,
		"pm10": 37.0,
		"quality": "优",
		"wendu": "29",
		"ganmao": "各类人群可自由活动",
		"forecast": [
			{
    
    
				"date": "10",
				"high": "高温 39℃",
				"low": "低温 27℃",
				"ymd": "2023-07-10",
				"week": "星期一",
				"sunrise": "04:55",
				"sunset": "19:44",
				"aqi": 91,
				"fx": "东北风",
				"fl": "2级",
				"type": "多云",
				"notice": "阴晴之间,谨防紫外线侵扰"
			},
			{
    
    
				"date": "11",
				"high": "高温 35℃",
				"low": "低温 28℃",
				"ymd": "2023-07-11",
				"week": "星期二",
				"sunrise": "04:55",
				"sunset": "19:44",
				"aqi": 97,
				"fx": "东南风",
				"fl": "2级",
				"type": "多云",
				"notice": "阴晴之间,谨防紫外线侵扰"
			},
			{
    
    
				"date": "12",
				"high": "高温 31℃",
				"low": "低温 25℃",
				"ymd": "2023-07-12",
				"week": "星期三",
				"sunrise": "04:56",
				"sunset": "19:43",
				"aqi": 78,
				"fx": "东风",
				"fl": "1级",
				"type": "中雨",
				"notice": "记得随身携带雨伞哦"
			},
			{
    
    
				"date": "13",
				"high": "高温 34℃",
				"low": "低温 24℃",
				"ymd": "2023-07-13",
				"week": "星期四",
				"sunrise": "04:57",
				"sunset": "19:43",
				"aqi": 91,
				"fx": "西南风",
				"fl": "2级",
				"type": "小雨",
				"notice": "雨虽小,注意保暖别感冒"
			},
			{
    
    
				"date": "14",
				"high": "高温 34℃",
				"low": "低温 24℃",
				"ymd": "2023-07-14",
				"week": "星期五",
				"sunrise": "04:57",
				"sunset": "19:43",
				"aqi": 98,
				"fx": "西北风",
				"fl": "3级",
				"type": "晴",
				"notice": "愿你拥有比阳光明媚的心情"
			},
			{
    
    
				"date": "15",
				"high": "高温 35℃",
				"low": "低温 25℃",
				"ymd": "2023-07-15",
				"week": "星期六",
				"sunrise": "04:58",
				"sunset": "19:42",
				"aqi": 69,
				"fx": "西北风",
				"fl": "3级",
				"type": "晴",
				"notice": "愿你拥有比阳光明媚的心情"
			},
			{
    
    
				"date": "16",
				"high": "高温 36℃",
				"low": "低温 22℃",
				"ymd": "2023-07-16",
				"week": "星期日",
				"sunrise": "04:59",
				"sunset": "19:41",
				"aqi": 60,
				"fx": "东北风",
				"fl": "2级",
				"type": "晴",
				"notice": "愿你拥有比阳光明媚的心情"
			},
			{
    
    
				"date": "17",
				"high": "高温 37℃",
				"low": "低温 23℃",
				"ymd": "2023-07-17",
				"week": "星期一",
				"sunrise": "05:00",
				"sunset": "19:41",
				"aqi": 59,
				"fx": "东南风",
				"fl": "2级",
				"type": "晴",
				"notice": "愿你拥有比阳光明媚的心情"
			},
			{
    
    
				"date": "18",
				"high": "高温 39℃",
				"low": "低温 25℃",
				"ymd": "2023-07-18",
				"week": "星期二",
				"sunrise": "05:01",
				"sunset": "19:40",
				"aqi": 85,
				"fx": "东风",
				"fl": "2级",
				"type": "小雨",
				"notice": "雨虽小,注意保暖别感冒"
			},
			{
    
    
				"date": "19",
				"high": "高温 38℃",
				"low": "低温 24℃",
				"ymd": "2023-07-19",
				"week": "星期三",
				"sunrise": "05:01",
				"sunset": "19:40",
				"aqi": 77,
				"fx": "东风",
				"fl": "2级",
				"type": "晴",
				"notice": "愿你拥有比阳光明媚的心情"
			},
			{
    
    
				"date": "20",
				"high": "高温 39℃",
				"low": "低温 25℃",
				"ymd": "2023-07-20",
				"week": "星期四",
				"sunrise": "05:02",
				"sunset": "19:39",
				"aqi": 54,
				"fx": "东南风",
				"fl": "2级",
				"type": "小雨",
				"notice": "雨虽小,注意保暖别感冒"
			},
			{
    
    
				"date": "21",
				"high": "高温 36℃",
				"low": "低温 23℃",
				"ymd": "2023-07-21",
				"week": "星期五",
				"sunrise": "05:03",
				"sunset": "19:38",
				"aqi": 65,
				"fx": "东南风",
				"fl": "2级",
				"type": "多云",
				"notice": "阴晴之间,谨防紫外线侵扰"
			},
			{
    
    
				"date": "22",
				"high": "高温 38℃",
				"low": "低温 25℃",
				"ymd": "2023-07-22",
				"week": "星期六",
				"sunrise": "05:04",
				"sunset": "19:37",
				"aqi": 47,
				"fx": "东风",
				"fl": "2级",
				"type": "中雨",
				"notice": "记得随身携带雨伞哦"
			},
			{
    
    
				"date": "23",
				"high": "高温 38℃",
				"low": "低温 24℃",
				"ymd": "2023-07-23",
				"week": "星期日",
				"sunrise": "05:05",
				"sunset": "19:37",
				"aqi": 49,
				"fx": "北风",
				"fl": "2级",
				"type": "暴雨",
				"notice": "关好门窗,外出避开低洼地"
			},
			{
    
    
				"date": "24",
				"high": "高温 30℃",
				"low": "低温 21℃",
				"ymd": "2023-07-24",
				"week": "星期一",
				"sunrise": "05:06",
				"sunset": "19:36",
				"aqi": 46,
				"fx": "东北风",
				"fl": "1级",
				"type": "中雨",
				"notice": "记得随身携带雨伞哦"
			}
		],
		"yesterday": {
    
    
			"date": "09",
			"high": "高温 38℃",
			"low": "低温 25℃",
			"ymd": "2023-07-09",
			"week": "星期日",
			"sunrise": "04:54",
			"sunset": "19:45",
			"aqi": 101,
			"fx": "西北风",
			"fl": "2级",
			"type": "多云",
			"notice": "阴晴之间,谨防紫外线侵扰"
		}
	}
}
完整代码结构

头文件 MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMessageBox>

#include <QNetworkAccessManager>
#include <QNetworkReply>

QT_BEGIN_NAMESPACE
namespace Ui {
    
     class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    
    
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

protected:
    void getWeatherInfo(QString cityCode);

private:
    void onReplied(QNetworkReply *reply);

private:
    QNetworkAccessManager *networkManager;
};
#endif // MAINWINDOW_H


主文件 MainWindow.cpp

#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    
    
    ui->setupUi(this);

    networkManager = new QNetworkAccessManager(this);
    connect(networkManager,&QNetworkAccessManager::finished,this,&MainWindow::onReplied);

    getWeatherInfo("101010100");
}

MainWindow::~MainWindow()
{
    
    
    delete ui;
}

void MainWindow::getWeatherInfo(QString cityCode)
{
    
    
    QUrl url("http://t.weather.itboy.net/api/weather/city/"+cityCode);
    networkManager->get(QNetworkRequest(url));
}

void MainWindow::onReplied(QNetworkReply *reply)
{
    
    
    qDebug() << "request successfully!!!";

    int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    qDebug() << "status code:" << statusCode;
    qDebug() << "url:" << reply->url();
    qDebug() << "operation:" << reply->operation();
    qDebug() << "raw header:" << reply->rawHeaderList();

    if(reply->error()!=QNetworkReply::NoError||statusCode!=200){
    
    
        qDebug() << reply->errorString().toLatin1().data();
        QMessageBox::critical(this,"错误","无法请求接口,请检查网络是否连接正确",QMessageBox::Ok);
    }else{
    
    
        QByteArray buff = reply->readAll();
        qDebug() << buff.data();
    }

    reply->deleteLater();
}



猜你喜欢

转载自blog.csdn.net/delete_you/article/details/131630959