QT软件开发: 解析JSON数据(QJsonX)

一、前言

本篇文章介绍使用QJsonDocument、QJsonObject、QJsonArray来解析JSON数据。


     QJsonDocument类提供了一种读取和写入JSON文档的方法。

     QJsonDocument是一个封装完整JSON文档的类,可以从UTF-8编码的基于文本的表示以及Qt自己的二进制格式读取和写入此文档。

     可以使用QJsonDocument::fromJson()将JSON文档从基于文本的表示转换为QJsonDocument.toJson()将其转换回文本。解析器非常快速高效,可以将JSON转换为Qt使用的二进制表示形式。

    已解析文档的有效性可以使用!isNull()

    可以使用isArray()和isObject()查询文档,确定它是包含数组还是对象。可以使用array()或          object()检索文档中包含的数组或对象,然后进行读取或操作。

    还可以使用fromBinaryData()或fromRawData()从存储的二进制表示形式创建文档。


二、解析JSON示例代码

2.1 json数据示例

{
    "streams": [
        {
            "index": 0,
            "codec_name": "mpeg1video",
            "codec_long_name": "MPEG-1 video",
            "codec_type": "video",
            "codec_time_base": "1/25",
            "codec_tag_string": "mp4v",
            "codec_tag": "0x7634706d",
            "width": 1920,
            "height": 1080,
            "coded_width": 0,
            "coded_height": 0,
            "has_b_frames": 1,
            "sample_aspect_ratio": "1:1",
            "display_aspect_ratio": "16:9",
            "pix_fmt": "yuv420p",
            "level": -99,
            "color_range": "tv",
            "chroma_location": "center",
            "refs": 1,
            "r_frame_rate": "25/1",
            "avg_frame_rate": "25/1",
            "time_base": "1/90000",
            "start_pts": 900,
            "start_time": "0.010000",
            "duration_ts": 6411600,
            "duration": "71.240000",
            "bit_rate": "104857200",
            "max_bit_rate": "104857200",
            "nb_frames": "1781",
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0
            },
            "tags": {
                "language": "und",
                "handler_name": "VideoHandler"
            }
        },
        {
            "index": 1,
            "codec_name": "mp3",
            "codec_long_name": "MP3 (MPEG audio layer 3)",
            "codec_type": "audio",
            "codec_time_base": "1/48000",
            "codec_tag_string": "mp4a",
            "codec_tag": "0x6134706d",
            "sample_fmt": "fltp",
            "sample_rate": "48000",
            "channels": 2,
            "channel_layout": "stereo",
            "bits_per_sample": 0,
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0",
            "time_base": "1/48000",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 3420288,
            "duration": "71.256000",
            "bit_rate": "384000",
            "max_bit_rate": "384000",
            "nb_frames": "2969",
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0
            },
            "tags": {
                "language": "und",
                "handler_name": "SoundHandler"
            }
        }
    ]
}

2.2 解析代码示例 

这个JSON数据是描述一个视频的详细信息的,是通过ffprobe.exe命令返回的。

代码如下: 

1./*
工程: ASS_SubtitleVideoPlayer
日期: 2021-09-07
作者: DS小龙哥
环境: win10 QT5.12.6 MinGW32
功能: 获取视频尺寸
*/
QSize Widget::GetVideoSize(QString video_name)
{
    QString cmd=QString("ffprobe.exe -v quiet -of json -i %1 -show_streams").arg(video_name);
    qDebug()<<"cmd:"<<cmd;
    qDebug()<<"当前路径:"<<QCoreApplication::applicationDirPath();
 
    QProcess process;
    process.setWorkingDirectory(QCoreApplication::applicationDirPath());
    process.start(cmd);
    process.waitForFinished();
    process.waitForReadyRead();
 
    QByteArray qba  = process.readAll();
    //qDebug()<<"读取的数据:"<<qba;
    
    QJsonParseError jsonError;
    // 转化为 JSON 文档
    QJsonDocument doucment = QJsonDocument::fromJson(qba, &jsonError);
 
    //解析未发生错误
    if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError))
    {
        //JSON文档为对象
        if (doucment.isObject())
        {
            //转化为对象
            QJsonObject object = doucment.object();
            //判断是否包含指定的key
            if (object.contains("streams"))
            {
                QJsonValue arrayValue = object.value("streams");
                QJsonArray array = arrayValue.toArray();
                for(int i=0;i<array.size();i++)
                {
                    QJsonValue Array = array.at(i);
                    QJsonObject data = Array.toObject();
 
                    //取出对应的值: 这里得到视频的宽和高
                    int width = data["width"].toInt();
                    int height = data["height"].toInt();
                    return QSize(width,height);
                 }
            }
        }
    }
    return QSize(0,0);
}

三、JSON解析示例:  简单的数据 

3.1 数据示例

{
    "code": 0,
    "data": "1424237430621474816",// 具体播放的视频id
    "msg": "操作成功",
    "success": true
}

3.2 代码示例

这是解析服务器返回的JSON数据。

/*
日期: 2021-08-13
作者: DS小龙哥
环境: win10 QT5.12.6 MinGW32
功能: 网络请求返回的结果
*/
void Widget::slot_request_videoID_replyFinished(QNetworkReply *reply)
{
    QString err_code;
    QByteArray read_data;
    int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    read_data=reply->readAll();
 
    if(200 != statusCode)
    {
        err_code=tr("视频ID:上传错误,错误代码:%1\n").arg(statusCode);
        return;
    }
 
    qDebug()<<"视频ID:"<<read_data;
 
    QJsonParseError jsonError;
 
    // 转化为 JSON 文档
    QJsonDocument doucment = QJsonDocument::fromJson(read_data, &jsonError);
 
    //解析未发生错误
    if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError))
    {
        //JSON文档为对象
        if (doucment.isObject())
        {
            //转化为对象
            QJsonObject object = doucment.object();
 
            //包含指定的key
            if (object.contains("success"))
            {
                // 获取指定 key 对应的 value
                QJsonValue value = object.value("success");
                // 判断 value 是否为对象
                if (value.isBool())
                {
                    bool success=value.toBool();
                    qDebug() << "success:" << success;
 
                    if(success)
                    {
                        //包含指定的key
                        if (object.contains("data"))
                        {
                            // 获取指定 key 对应的 value
                            QJsonValue value = object.value("data");
                            // 判断 value 是否为对象
                            if (value.isString())
                            {
                                m_video_id = value.toString();
                                qDebug() << "m_video_id:" << m_video_id;
                            }
                        }
                    }
                    else
                    {
                        //包含指定的key
                        if (object.contains("msg"))
                        {
                            // 获取指定 key 对应的 value
                            QJsonValue value = object.value("msg");
                            // 判断 value 是否为对象
                            if (value.isString())
                            {
                                QString msg = value.toString();
                                qDebug() << "视频ID获取:" << msg;
                            }
                        }
                        m_video_id="88888888888888888";
                    }
                }
            }
         }
      }
    else
    {
        qDebug()<<"视频ID:JSON解析错误.";
    }
}
上一篇:让测试工作为项目运行保驾护航 | 带你学《Java面向对象编程》之一百


下一篇:证监会信息中心主任张野:区块链绝对去中心化不成立,视应用场景而定