【QT】QJson的创建与读取解析 + 实例天气获取并解析

555 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Json的基本使用

QJsonObject:存储Json对象

// 构建 json对象
    QJsonObject m_json;
    m_json.insert("name","stylle");
    m_json.insert("age",19);
    qDebug() << m_json << endl;

输出效果

QJsonObject({"age":19,"name":"stylle"})

QJsonArray :存储Json对象数组

// 构建和解析 json数组
    QJsonArray m_jsonArry;
    m_jsonArry.append(m_json);
    m_jsonArry.append(m_json);
    qDebug() << m_jsonArry <<endl;
    qDebug() << m_json.value("name").toString() << endl;
    QJsonObject m_json2 = m_jsonArry.at(0).toObject();
    qDebug() << m_json2.value("age").toInt() << endl;

输出效果

QJsonArray([{"age":19,"name":"stylle"},{"age":19,"name":"stylle"}]) "stylle" 19

QJsonDocument:解析Json文档

    // 构建 JSON 文档
    QJsonDocument document;
    document.setObject(m_json);
    QByteArray byt = document.toJson(QJsonDocument::Compact);
    QString strJson(byt);

    qDebug() << strJson;

输出效果

"{"age":19,"name":"stylle"}"

QJsonValue :解析JsonObject中对应键的值

QJsonValue &	operator=(QJsonValue &&other)
QJsonValue &	operator=(const QJsonValue &other)
	~QJsonValue()
bool 	isArray() const
bool 	isBool() const
bool 	isDouble() const
bool 	isNull() const
bool 	isObject() const
bool 	isString() const
bool 	isUndefined() const
void 	swap(QJsonValue &other)
QJsonArray 	toArray(const QJsonArray &defaultValue) const
QJsonArray 	toArray() const
bool 	toBool(bool defaultValue = false) const
double 	toDouble(double defaultValue = 0) const
int 	toInt(int defaultValue = 0) const
QJsonObject 	toObject(const QJsonObject &defaultValue) const
QJsonObject 	toObject() const
QString 	toString() const
QString 	toString(const QString &defaultValue) const
QVariant 	toVariant() const
QJsonValue::Type 	type() const
bool 	operator!=(const QJsonValue &other) const
bool 	operator==(const QJsonValue &other) const
const QJsonValue 	operator[](const QString &key) const
const QJsonValue 	operator[](QStringView key) const
const QJsonValue 	operator[](QLatin1String key) const
const QJsonValue 	operator[](int i) const

可以看到该类的成员函数包含了大部分的数据转换接口、数据类型判断接口和一些运算和取值接口。

QJsonParseError:存储解析Json过程中出现的错误

QJsonParseError err;
// 解析QByteArray 类型的数据比如串口和网络接受到的数据类型
QJsonDocument json_recv = QJsonDocument::fromJson(byt, &err);
qDebug() << err.error;
返回数值错误对照表格
不变量 	 								值 	描述
QJsonParseError::NoError 	0 	没有发生错误
QJsonParseError::UnterminatedObject 	1 	对象未正确使用大括号
QJsonParseError::MissingNameSeparator 	2 	缺少分隔不同项目的逗号
QJsonParseError::UnterminatedArray 	3 	数组未正确用方括号括起来
QJsonParseError::MissingValueSeparator 	4 	缺少将键与对象内的值分隔开的冒号
QJsonParseError::IllegalValue 	5 	该值是非法的
QJsonParseError::TerminationByNumber 	6 	输入流在解析数字时结束
QJsonParseError::IllegalNumber 	7 	数字格式不正确
QJsonParseError::IllegalEscapeSequence 	8 	输入中发生非法的转义序列
QJsonParseError::IllegalUTF8String 	9 	输入中出现非法的UTF8序列
QJsonParseError::UnterminatedString 	10 	字符串未以引号终止
QJsonParseError::MissingObject 	11 	预期有对象,但找不到
QJsonParseError::DeepNesting 	12 	JSON文档的嵌套太深,解析器无法对其进行解析
QJsonParseError::DocumentTooLarge 	13 	JSON文档太大,解析器无法解析它
QJsonParseError::GarbageAtEnd 	14 	解析的文档末尾包含其他垃圾字符
公有成员函数文档

实例分析:获取天气

Json数据分析

这里需要用到的api地址:"wthrcdn.etouch.cn/weather_min…" 查询的城市:成都 返回的信息如下

{"data":{ "yesterday":{ "date":"20日星期六", "high":"高温 14℃", "fx":"东北风", "low":"低温 12℃", "fl":"", "type":"霾" }, "city":"成都", "forecast":[ {"date":"21日星期天", "high":"高温 13℃", "fengli":"", "low":"低温 8℃", "fengxiang":"东北风", "type":"阴" }, {"date":"22日星期一", "high":"高温 14℃", "fengli":"", "low":"低温 7℃", "fengxiang":"南风", "type":"阴" }, {"date":"23日星期二", "high":"高温 14℃", "fengli":"", "low":"低温 6℃", "fengxiang":"南风", "type":"阴" }, {"date":"24日星期三", "high":"高温 14℃", "fengli":"", "low":"低温 7℃", "fengxiang":"南风", "type":"阴" }, {"date":"25日星期四", "high":"高温 14℃", "fengli":"", "low":"低温 7℃", "fengxiang":"南风", "type":"多云"}], "ganmao":"感冒低发期,天气舒适,请注意多吃蔬菜水果,多喝水哦。","wendu":"9"}, "status":1000, "desc":"OK" } 这样可能看的不明确看图 在这里插入图片描述 可以看到返回的数据第一个{}包含三个内容的json数组,数组内容包含“data”,“status”,”desc“,然后我们这个实例需要获取当天的天气信息可以看到数据是在“data”中,data又是一个数组有"yesterday","city","forecast"然后当天的天气信息是在“foreacast”中,又是一个数组,而该json数组的第一个值就是我们需要的信息,所以我们得到以下关系;

object->“data”->“forecast”[0]

得知这个关系式过后我们开始写我们的代码。

netJson.cpp

#include "netjson.h"
#include "ui_netjson.h"

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

    manager = new QNetworkAccessManager(this);  //新建QNetworkAccessManager对象
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(readFinished(QNetworkReply*)));//关联信号和槽
}

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

// 请求网络api接口获取数据
void netJson::on_btn_serach_clicked()
{
    QString url = "http://wthrcdn.etouch.cn/weather_mini?city=" + ui->edit_addr->text(); //获得需要查询天气的城市名称
    QNetworkRequest quest;
    quest.setUrl(QUrl(url));
    quest.setHeader(QNetworkRequest::UserAgentHeader, "QT clinet");
    /*发送get网络请求*/
    manager->get(quest);
}

// 接受网络接口返回的数据然后处理显示
void netJson::readFinished(QNetworkReply *reply)
{
    QByteArray byte = reply->readAll(); // 获取网页api返回的数据
    ui->edit_data->clear();
    ui->edit_data->append("json信息:");
    ui->edit_data->append(byte); // 将获取的数据添加到json数据框做解析
    QJsonParseError err;
    QJsonDocument m_jDocm = QJsonDocument::fromJson(byte,&err);
    if (err.error == QJsonParseError::NoError) // 如果解析没有错误再继续下面的操作
    {
        QJsonObject object = m_jDocm.object(); // 转换为json数组
        QJsonValue JsonData = object.value("data");
        QJsonObject JsonDataArray = JsonData.toObject();
        QJsonValue JsonDataForecast = JsonDataArray.value("forecast");
        QJsonArray valueArray = JsonDataForecast.toArray();
        QJsonObject valueObject = valueArray.at(0).toObject(); // 得到我们需要的数组

//        "date": "21日星期天",
//        "high": "高温 13℃",
//        "fengli": "<![CDATA[2级]]>",
//        "low": "低温 8℃",
//        "fengxiang": "东北风",
//        "type": "阴"
        QString date = valueObject.value("date").toString();
        QString tempMax = valueObject.value("high").toString();
        QString tempMin = valueObject.value("low").toString();
        QString wather = valueObject.value("type").toString();

        ui->edit_json->clear();
        ui->edit_json->append("解释信息:");
        ui->edit_json->append("日期:" + date);
        ui->edit_json->append("最高温度:" + tempMax);
        ui->edit_json->append("最低温度:" + tempMin);
        ui->edit_json->append("天气类型:" + wather);
    }else{
        ui->edit_data->append(err.errorString());
        qDebug() << err.errorString() << endl;;
    }
}

netJson.h

#ifndef NETJSON_H
#define NETJSON_H

#include <QWidget>
#include <QDebug>
/* 解析网页需要用到的头文件 */
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
/* 解析json数据要用到的头文件 */
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

QT_BEGIN_NAMESPACE
namespace Ui { class netJson; }
QT_END_NAMESPACE

class netJson : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_btn_serach_clicked();
    void readFinished(QNetworkReply *reply);

private:
    Ui::netJson *ui;
    QNetworkAccessManager *manager;  //请求句柄
};
#endif // NETJSON_H

这里需要注意的是要使用网络库请求api时应再.pro工程中包含

QT       +=  network

最终效果+工程下载

代码中转换为QJsonValue类型转为QJsonObject类型时应做isObject判断,但QJsonObject转换为QJsonValue时应做contains(“key”)判断; 在这里插入图片描述「netJson」,点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载,极速在线查看享用。 链接:www.aliyundrive.com/s/u549stWWH…