本文已参与「新人创作礼」活动,一起开启掘金创作之路。
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…