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

在上一篇文章《用户登录及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数据解析功能。

详细的说,每当发送查词请求后,server就会返回JSON格式的单词内容。因此,我们仅仅须要在处理server返回数据的函数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解析,因此非常easy得到单词的各个部分的内容
            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

时间: 2024-10-12 10:00:37

【Qt编程】基于Qt的词典开发系列&lt;九&gt;--JSON数据解析的相关文章

iOS开发笔记3:XML/JSON数据解析

这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法.XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSerialization. 1.XML解析之NSXMLParser NSXMLParser是iOS原生的XML解析方式,采用SAX方式进行解析,特点是解析的时候从根元素开始,按顺序依次对每一个元素进行解析. 以下图所示XML文档为例进行解析 (1)首先是实例化一个NSXMLParser,设置代理监听解析过

【Qt编程】基于Qt的词典开发系列&lt;七&gt;--调用网络API

前面文章中我们实现了本地的词库设计,可以完成本地的查词功能,那么这篇文章主要讲一讲如何通过调用网络的api来实现词典的网络查词功能. 词典API的选择 基本上市面上做词典软件的公司都有对应的api,比如说有道.金山等等,不过一般都需要api key,有点麻烦,于是乎,我就找了个简单好用的扇贝网API:http://www.shanbay.com/help/developer/api/ 奇怪的是,该api说要停用了,可以从我去年暑假完成该软件制作,到如今为止,还能正常使用. 扇贝词典api的使用

【Qt编程】基于Qt的词典开发系列&lt;二&gt;--本地词典的设计

我设计的词典不仅可以实现在线查单词,而且一个重大特色就是具有丰富的本地词典库:我默认加入了八个类型的词典,如下所示: 由于是本人是通信专业,因此加入了华为通信词典.电子工程词典,又由于我喜爱编程,也加入了c语言基本函数词典.下面介绍如何设计本地词典: 词典类型的选择 当然是txt格式的最好了,因为我们可以用程序直接进行读取.可是网上词典一般都是用mdx格式.ld2格式的,我无法用Qt来直接读取.最终,经过不断摸索,网上查找,发现我们可以将mdx格式的词典通过软件转化为txt格式的! mdx词典的

【Qt编程】基于Qt的词典开发系列&lt;九&gt;--JSON数据解析

在上一篇文章<用户登录及API调用的实现>中,我通过程序实现了用户登录及API调用的实现,从而能够实现网络查词.添词的操作.但是,从上文中可以看到,调用API后返回的是JSON格式的数据,如下图所示(在QtCreator中的显示): 为了更好的观察JSON格式,我整理后显示如下: 显然,为了显示查词的结果,我们必须在上图中提取有用的信息,并正确的显示出来.上图中每一行内容的意思我已经在文章<调用网络API>中作了解释.我在词典中选择想要显示的内容有:单词本身.单词ID.中文解释.英

【Qt编程】基于Qt的词典开发系列--后序

从去年八月份到现在,总算完成了词典的编写以及相关技术文档的编辑工作.从整个过程来说,文档的编写比程序的实现耗费的时间更多.基于Qt的词典开发系列文章,大致包含了在编写词典软件过程中遇到的技术重点与难点.每篇文章都完成了一个小的功能,所给的代码都基本上是可以独立运行的.本系列文章对于想要自己动手完成词典软件的程序员来说具有很好的参考价值,对于想要编写其它软件的人来说也具有参考意义. 词典软件制作的初衷 在2013的年终总结中,我提过想要学习一门界面编程语言,后来就选中了Qt.于是在2014年上半年

【Qt编程】基于Qt的词典开发系列&lt;三&gt;--开始菜单的设计

这篇文章讲讲如何实现开始菜单(或者称为主菜单)的设计.什么是开始菜单呢?我们拿常用的软件来用图例说明,大多数软件的开始菜单在左下角,如下图: 1.window 7的开始菜单 2.有道词典的主菜单 3.QQ的开始菜单 4.我写的词典软件的开始菜单 当你左键单击开始菜单时,就会弹出相应的菜单选项,然后你就可以进行相关操作.本文只讲如何实现点击按钮,弹出菜单功能,至于点击菜单后的事件需要你自己编写.当然,关于右击按钮出现菜单的方法,则是要重写qt自带的函数,至于具体操作可以百度. 要想使按钮实现左键单

【Qt编程】基于Qt的词典开发系列&lt;三&gt;--界面美化设计

本文讲一讲界面设计,作品要面向用户,界面设计的好坏直接影响到用户的体验.现在的窗口设计基本都是扁平化的,你可以从window  XP与window 8的窗口可以明显感觉出来.当然除了窗口本身的效果,窗口中各种控件的特效也是特别重要的一环.下面讲讲我在词典软件中的一些设计:说到界面美化的设计,不得不提到美工,一个好的美工是想当的重要!软件毕竟少不了图标,而不懂美工的我,也就只能在网上使用别人的图标了. 如何得到网上的图标? 直接百度就可以了,当然还有另一种方法:就是从别人的文件中提取这些图标文件.

linux网络编程 基于TCP的程序开发

面向连接的TCP程序设计 基于TCP的程序开发分为服务器端和客户端两部分,常见的核心步骤和流程: 其实按照上面这个流程调用系统API确实可以完全实现应用层程序的开发,一点问题没有.可随着时间的推移,你会觉得这样子的开发毫无激情.为什么TCP的开发就要按照这样的流程来呢?而且一般出的问题几乎都不在这几个系统调用上,原因何在?当我们弄清网络开发的本质,协议栈的设计原理.数据流向等这些问题的答案也就会慢慢浮出水面了.接下来这几篇博文主要是围绕网络编程展开,目的是引出后面对于Linux下TCP/IP协议

iOS开发——XML/JSON数据解析

除了XML和Json,文中还涉及到的一些知识:第三方类库的使用,获取本地文件内容,网站API使用,GCD多线程编程,不做详细介绍,在代码出现的地方会注明. 先安利一波: Json XML 大数据时代,我们需要从网络中获取海量的新鲜的各种信息,就不免要跟着两个家伙打交道,这是两种结构化的数据交换格式.一般来讲,我们会从网络获取XML或者Json格式的数据,这些数据有着特定的数据结构,必须对其进行解析,得到我们可以处理的数据.所谓“解析”,就是从事先规定好的格式串中提取数据.解析的前提是数据的提供方