企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 【Qt编程】基于Qt的词典开发系列--JSON数据解析 在上一篇文章《[用户登录及API调用的实现](http://blog.csdn.net/tengweitw/article/details/45932429)》中,我通过程序实现了用户登录及API调用的实现,从而能够实现网络查词、添词的操作。但是,从上文中可以看到,调用API后返回的是JSON格式的数据,如下图所示(在QtCreator中的显示):  ![](https://box.kancloud.cn/2016-01-15_5698c1c86f5d8.jpg) 为了更好的观察JSON格式,我整理后显示如下:  ![](https://box.kancloud.cn/2016-01-15_5698c1c87fa2a.jpg) 显然,为了显示查词的结果,我们必须在上图中提取有用的信息,并正确的显示出来。上图中每一行内容的意思我已经在文章《[调用网络API](http://blog.csdn.net/tengweitw/article/details/45484803)》中作了解释。我在词典中选择想要显示的内容有:单词本身、单词ID、中文解释、英文解释、音标、发音音频,与之对应上图中的content、learning_id、definition、en_definitions、pron、audio。 为了获取这些内容,我们必须进行对上面的JSON格式数据(关于什么是JSON格式,可以自己百度)进行解析。在Qt 4中,没有对应的模块,必须单独加入相应的函数库,当然也可以自己根据JSON的格式自己写程序提取你想要的内容,只不过比较麻烦而已。在Qt5中,自带有对应的JSON解析模块,因此不用自己来写解析函数了,只需要调用相应的函数。**下面给出具体的程序实现:** 程序的主体框架与文章《[用户登录及API调用的实现](http://blog.csdn.net/tengweitw/article/details/45932429)》中的一样,只是在其中加入了JSON数据解析功能。具体的说,每当发送查词请求后,服务器就会返回JSON格式的单词内容。因此,我们只需要在处理服务器返回数据的函数replyfinished()函数中对应的查词操作QueryWordAction中进行JSON数据解析,将我们需要的内容存储到我们定义的Word类中。其中,word的定义如下:  ![](https://box.kancloud.cn/2016-01-15_5698c1c89334c.jpg) 由于只是在上文《[用户登录及API调用的实现](http://blog.csdn.net/tengweitw/article/details/45932429)》的程序中加了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(); } ~~~ **运行结果如下图:**  ![](https://box.kancloud.cn/2016-01-15_5698c1c8a3912.jpg)