【Qt编程】基于Qt的词典开发系列<九>--JSON数据解析-阿里云开发者社区

开发者社区> 开发与运维> 正文

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

简介: 在上一篇文章《用户登录及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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章