【Qt编程】基于Qt的词典开发系列<九>--JSON数据解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 在上一篇文章《用户登录及API调用的实现》中,我通过程序实现了用户登录及API调用的实现,从而能够实现网络查词、添词的操作。

在上一篇文章《用户登录及API调用的实现》中,我通过程序实现了用户登录及API调用的实现,从而能够实现网络查词、添词的操作。但是,从上文中可以看到,调用API后返回的是JSON格式的数据,如下图所示(在QtCreator中的显示):
这里写图片描述

为了更好的观察JSON格式,我整理后显示如下:
这里写图片描述

显然,为了显示查词的结果,我们必须在上图中提取有用的信息,并正确的显示出来。上图中每一行内容的意思我已经在文章《调用网络API》中作了解释。我在词典中选择想要显示的内容有:单词本身、单词ID、中文解释、英文解释、音标、发音音频,与之对应上图中的content、learning_id、definition、en_definitions、pron、audio。

为了获取这些内容,我们必须进行对上面的JSON格式数据(关于什么是JSON格式,可以自己百度)进行解析。在Qt 4中,没有对应的模块,必须单独加入相应的函数库,当然也可以自己根据JSON的格式自己写程序提取你想要的内容,只不过比较麻烦而已。在Qt5中,自带有对应的JSON解析模块,因此不用自己来写解析函数了,只需要调用相应的函数。下面给出具体的程序实现:

程序的主体框架与文章《用户登录及API调用的实现》中的一样,只是在其中加入了JSON数据解析功能。具体的说,每当发送查词请求后,服务器就会返回JSON格式的单词内容。因此,我们只需要在处理服务器返回数据的函数replyfinished()函数中对应的查词操作QueryWordAction中进行JSON数据解析,将我们需要的内容存储到我们定义的Word类中。其中,word的定义如下:
这里写图片描述

由于只是在上文《用户登录及API调用的实现》的程序中加了JSON解析的部分,其它部分基本没变,所以程序的运行流程及思路可见上文。当然,程序中的注释也算比较详细,因此不作具体说明。只需要将下面五个源文件放入空的Qt项目中即可。注意:是在Qt 5中,且需要在其.pro文件中加入语句:QT +=core gui network webkit multimedia。具体的源文件如下


1、word.h文件

#ifndef WORD_H
#define WORD_H
#include<QString>
#include<List>
#include <QJsonObject>
#include<QtMultimedia/QMediaPlayer>
#include<QUrl>
class Word
{
public:
    explicit Word();
    Word(const Word& word);
    ~Word();
public:

    QString name;//单词本身
    QString learning_id;//单词ID
    QString definition;//单词中文解释
    QString en_definitions;//单词英文解释
    QString pron;//单词音标
    QString audio;//单词的发音音频

    void clear();
};

#endif // WORD_H

2、word.cpp文件

#include "word.h"

Word::Word()
{

}
Word::Word(const Word &w)
{
    name=w.name;
    learning_id=w.learning_id;
    definition=w.definition;
    en_definitions=w.en_definitions;
    pron=w.pron;
    audio=w.audio;

}

Word::~Word()
{
}




void Word::clear()//清除内容
{
    name="";
    learning_id="";
    definition="";
    en_definitions="";
    pron="";
    audio="";
   // this->examples=NULL;
}

3、network.h文件

#ifndef NETWORK_H
#define NETWORK_H
#include"word.h"

#include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include<QtNetwork/QNetworkReply>
#include<QtNetwork/QNetworkRequest>
#include<QtNetwork/QNetworkCookie>
#include<QtNetwork/QNetworkCookieJar>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
#include<QString>
#include<QDebug>
#include<QList>
#include<QUrl>
#include<QByteArray>

class netWork : public QObject
{
    Q_OBJECT
public:
    explicit netWork(QObject *parent = 0);
 //   ~netWork();


    enum HttpAction{NoAction,NetStudy,GetSessionidAction,LoginAction,QueryWordAction,AddWordAction,AddExampleAction,QueryWordExamplesAction};
    HttpAction httpAction;
    QNetworkAccessManager * http;
    QString sessionid;
    QString queryword;//要查询的单词
    QString nickname;
    QString username;
    QString password;
    bool isBusy;

    Word *gotword;//通过访问网络得到的单词信息
    QString getCookie(const QString &name);

    void loginShanbay();
    void queryWord(const QString &word);
    void queryExamples(QString learningid);
    void connectNet(QString username="nineheadedbird", QString password="123456");
    void addWord(const QString &word);

signals:

    void signalQueryFinished(Word *word);
    void connectSuccess();
    void connectFail();
    void verifySuccess();
    void verifyFail();
    void NetState(bool);
public slots:
    void replyfinished(QNetworkReply*);

};

#endif // NETWORK_H

4、network.cpp文件

#include "network.h"
#include<QList>
#include<QDesktopServices>
netWork::netWork(QObject *parent) :
    QObject(parent)
{
        http=new QNetworkAccessManager(this);
        http->setCookieJar(new QNetworkCookieJar(this));
        connect(http,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyfinished(QNetworkReply*)));
        isBusy=true;
        gotword=new Word();

}

QString netWork::getCookie(const QString &name)
{
    foreach(QNetworkCookie cookie , http->cookieJar()->cookiesForUrl(QUrl("http://www.shanbay.com/")))
    {
            //qDebug()<<cookie.name();
            if(cookie.name()==name)
            {
                return cookie.value();
            }
        }
        return "";
}


void netWork::loginShanbay()
{
       QNetworkRequest request;
       request.setUrl(QUrl("http://www.shanbay.com/accounts/login/"));
       request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
       request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3");
       request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
       request.setRawHeader("Cache-Control","max-age=0");
       request.setRawHeader("Connection","keep-alive");
       request.setRawHeader("Host","www.shanbay.com");
       request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
       request.setRawHeader("Origin","http//www.shanbay.com");
       request.setRawHeader("Referer","http://www.shanbay.com/accounts/login/");
       request.setRawHeader("Host","www.shanbay.com");
       request.setRawHeader("Content-Type","application/x-www-form-urlencoded");
       QByteArray postData;
       postData.append(QString("csrfmiddlewaretoken=%1&").arg(sessionid));
       postData.append(QString("username=%1&password=%2&").arg(QUrl::toPercentEncoding(username).constData()).arg(password));
       postData.append("login=登录&continue=home&u=1&next=");
       request.setHeader(QNetworkRequest::ContentLengthHeader,postData.size());
       httpAction=LoginAction;
       http->post(request,postData);
}

void netWork::queryWord(const QString &word)
{
      QNetworkRequest request;
      request.setUrl(QUrl("http://www.shanbay.com/api/word/"+word));
      request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
      request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3");
      request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
      request.setRawHeader("Cache-Control","max-age=0");
      request.setRawHeader("Connection","keep-alive");
      request.setRawHeader("Host","www.shanbay.com");
      request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
      httpAction=QueryWordAction;
      http->get(request);
}

void netWork::queryExamples(QString learningid)
{
    if(learningid=="0"){
           return;
       }
       QNetworkRequest request;
       request.setUrl(QUrl("http://www.shanbay.com/api/learning/examples/"+learningid));
       request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
       request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3");
       request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
       request.setRawHeader("Cache-Control","max-age=0");
       request.setRawHeader("Connection","keep-alive");
       request.setRawHeader("Host","www.shanbay.com");
       request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
       httpAction=QueryWordExamplesAction;
       http->get(request);
}


void netWork::addWord(const QString &word)
{
    if(word.isEmpty())
        qDebug()<<"你的输入有误";
    else
    {
        QNetworkRequest request;
        request.setUrl(QUrl("http://www.shanbay.com/api/learning/add/"+word));
        request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3");
        request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
        request.setRawHeader("Cache-Control","max-age=0");
        request.setRawHeader("Connection","keep-alive");
        request.setRawHeader("Host","www.shanbay.com");
        request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
        httpAction=AddWordAction;
        http->get(request);
    }
}

void netWork::connectNet(QString username, QString password)
{
        this->username=username;
        this->password=password;
         QNetworkRequest request;
        request.setUrl(QUrl("http://www.shanbay.com/accounts/login/"));
        request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3");
        request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
        request.setRawHeader("Cache-Control","max-age=0");
        request.setRawHeader("Connection","keep-alive");
        request.setRawHeader("Host","www.shanbay.com");
        request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
        httpAction=GetSessionidAction;
        http->get(request);
}

void netWork::replyfinished(QNetworkReply *reply)
{
    QByteArray wordInformation;
    QVariant status_code=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
 //  qDebug()<<"code_state="<<status_code;
    if(status_code==QVariant::Invalid)
        emit NetState(false);
    else
        emit NetState(true);
    QJsonDocument jsonDoc;
    QJsonObject jsonObj,vocObj,en_definitionsObj;

    switch(httpAction)
    {
    case NoAction:
        break;
    case GetSessionidAction:
        sessionid=getCookie("csrftoken");
        if(!sessionid.isEmpty()){
            emit connectSuccess();

            qDebug()<<("Connect successfully! Verifying username and password...");
           loginShanbay();
        }else{
            emit connectFail();

             qDebug()<<("Cannot connect! Please try to check the internet!");
        }

        break;
    case LoginAction:
        httpAction=NoAction;
        if(0==reply->readAll().size())
        {
            QString nickname=QUrl::fromPercentEncoding(getCookie("username").toLatin1());
            emit verifySuccess();

            qDebug()<<"Login successfully!"<<nickname;
            queryWord("hello");
        }else
        {
            emit verifyFail();
            qDebug()<<"Failed to login! Please check!";
        }
        break;
    case QueryWordAction://是在这里面进行JSON数据解析!
        qDebug()<<"----query word----";

        wordInformation=reply->readAll();
         qDebug()<<"the information of word in JSON format::\n";
         qDebug()<< wordInformation;
        jsonDoc=QJsonDocument::fromJson( wordInformation);
        if(!jsonDoc.isNull())
        {
            jsonObj=jsonDoc.object();
            vocObj=jsonObj.value("voc").toObject();//Qt5 自带JSON解析,因此很容易得到单词的各个部分的内容
            en_definitionsObj=vocObj.value("en_definitions").toObject();   
            gotword->clear();

            gotword->name=vocObj.value("content").toString();//单词本身

            gotword->learning_id=QString::number(jsonObj.value("learning_id").toDouble(),'g',15);
            gotword->definition=vocObj.value("definition").toString();//中文解释
            gotword->pron=vocObj.value("pron").toString();//单词音标


            gotword->pron=gotword->pron;
            gotword->audio=vocObj.value("audio").toString();

            //由于单词的英文解释有多项(词性、解释等等),我们将结果用html格式表示,并使得词性颜色设置为黑色
            for( QJsonObject::const_iterator it=en_definitionsObj.constBegin();it!=en_definitionsObj.constEnd();it++)
            {
                gotword->en_definitions+=QString("<br><font color='black'><b>%1. </b></font>").arg(it.key());
                if(it.value().isArray())
                {
                    foreach(QJsonValue jv,it.value().toArray())
                    {
                       gotword->en_definitions+=QString("%1; ").arg(jv.toString());
                    }
                }
                gotword->en_definitions+="<br>";

            }

            emit signalQueryFinished(gotword);
           //显示JSON解析后的数据
            qDebug()<<"name="<<gotword->name;
            qDebug()<<"word="<<gotword->learning_id;
            qDebug()<<"definition="<<gotword->definition;
            qDebug()<<"en_definitions="<<gotword->en_definitions;
            qDebug()<<"pron="<<gotword->pron;
            qDebug()<<"audio"<<gotword->audio;

            //进行网络发音
            QMediaPlayer *player = new QMediaPlayer();
                player->setMedia(QUrl(gotword->audio));
                player->play();
            if(gotword->learning_id!="0")//不是新单词
            {

                qDebug()<<"你学过这个单词";
            }

        }

        break;

    case QueryWordExamplesAction:
//            qDebug()<<"query word examples";
//             qDebug()<<reply->readAll();

            break;

    case AddWordAction:
//        qDebug()<<"add word";
        jsonDoc=QJsonDocument::fromJson(reply->readAll());
        if(!jsonDoc.isNull())
        {
            jsonObj=jsonDoc.object();
            //qDebug()<<"jsonObj"<<jsonObj;
            gotword->learning_id=QString::number(jsonObj.value("id").toDouble(),'g',15);
          //  qDebug()<<jsonObj.value("id").toDouble()<<"add word result learning id="<<gotword->learning_id<< (gotword->learning_id!="0");
         //   emit signalAddwordFinished(DICT::word->learning_id!="0");
         //   queryExamples(DICT::word->learning_id);
        }



    default:break;
    }
}

5、main.cpp文件

#include <QApplication>
#include "network.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    netWork *nW = new netWork();
    nW->connectNet();

    return a.exec();
}

运行结果如下图:
这里写图片描述


基于Qt的词典开发系列

  1. 词典框架设计及成品展示
  2. 本地词典的设计
  3. 开始菜单的设计
  4. 无边框窗口的缩放与拖动
  5. 无边框窗口的拖动
  6. 界面美化设计
  7. 调用网络API
  8. 用户登录及API调用的实现
  9. JSON数据解析
  10. 国际音标的显示
  11. 系统托盘的显示
  12. 调用讲述人
  13. 音频播放
  14. 自动补全功能
  15. HTML特殊字符及正则表达式
  16. 后序

作品下载地址(发布版):http://download.csdn.net/detail/tengweitw/8548767
作品下载地址(绿色版):http://download.csdn.net/detail/tengweitw/8830495
源码下载地址:http://download.csdn.net/detail/tengweitw/8830503


原文:http://blog.csdn.net/tengweitw/article/details/46506945
作者:nineheadedbird

目录
相关文章
|
2月前
|
消息中间件 存储 缓存
十万订单每秒热点数据架构优化实践深度解析
【11月更文挑战第20天】随着互联网技术的飞速发展,电子商务平台在高峰时段需要处理海量订单,这对系统的性能、稳定性和扩展性提出了极高的要求。尤其是在“双十一”、“618”等大型促销活动中,每秒需要处理数万甚至数十万笔订单,这对系统的热点数据处理能力构成了严峻挑战。本文将深入探讨如何优化架构以应对每秒十万订单级别的热点数据处理,从历史背景、功能点、业务场景、底层原理以及使用Java模拟示例等多个维度进行剖析。
58 8
|
13天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
2月前
|
数据采集 自然语言处理 搜索推荐
基于qwen2.5的长文本解析、数据预测与趋势分析、代码生成能力赋能esg报告分析
Qwen2.5是一款强大的生成式预训练语言模型,擅长自然语言理解和生成,支持长文本解析、数据预测、代码生成等复杂任务。Qwen-Long作为其变体,专为长上下文场景优化,适用于大型文档处理、知识图谱构建等。Qwen2.5在ESG报告解析、多Agent协作、数学模型生成等方面表现出色,提供灵活且高效的解决方案。
199 49
|
1月前
|
缓存 Java 调度
多线程编程核心:上下文切换深度解析
在现代计算机系统中,多线程编程已成为提高程序性能和响应速度的关键技术。然而,多线程编程中一个不可避免的概念就是上下文切换(Context Switching)。本文将深入探讨上下文切换的概念、原因、影响以及优化策略,帮助你在工作和学习中深入理解这一技术干货。
47 10
|
1月前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
48 8
|
1月前
|
算法 调度 开发者
多线程编程核心:上下文切换深度解析
在多线程编程中,上下文切换是一个至关重要的概念,它直接影响到程序的性能和响应速度。本文将深入探讨上下文切换的含义、原因、影响以及如何优化,帮助你在工作和学习中更好地理解和应用多线程技术。
42 4
|
1月前
|
XML JSON JavaScript
HttpGet 请求的响应处理:获取和解析数据
HttpGet 请求的响应处理:获取和解析数据
|
3月前
|
自然语言处理 数据可视化 前端开发
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
合合信息的智能文档处理“百宝箱”涵盖文档解析、向量化模型、测评工具等,解决了复杂文档解析、大模型问答幻觉、文档解析效果评估、知识库搭建、多语言文档翻译等问题。通过可视化解析工具 TextIn ParseX、向量化模型 acge-embedding 和文档解析测评工具 markdown_tester,百宝箱提升了文档处理的效率和精确度,适用于多种文档格式和语言环境,助力企业实现高效的信息管理和业务支持。
4100 5
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
|
2月前
|
存储 缓存 开发者
Python编程中的装饰器深度解析
本文将深入探讨Python语言的装饰器概念,通过实际代码示例展示如何创建和应用装饰器,并分析其背后的原理和作用。我们将从基础定义出发,逐步引导读者理解装饰器的高级用法,包括带参数的装饰器、多层装饰器以及装饰器与类方法的结合使用。文章旨在帮助初学者掌握这一强大工具,同时为有经验的开发者提供更深层次的理解和应用。
41 7
|
2月前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####

热门文章

最新文章

推荐镜像

更多