【Qt编程】基于Qt的词典开发系列九

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

{public:explicit Word();Word(const Word& word);~Word();public:QString name;//单词本身QString learning_id;//单词IDQString 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文件

: public QObject{Q_OBJECTpublic: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文件

::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/”))){//;if(cookie.name()==name){;}}return “”;}{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);elseemit 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 learninghljs-string”>”0″);// emit signalAddwordFinished(DICT::word->learning_id!=”0″);// queryExamples(DICT::word->learning_id);}default:break;}}你可能付出一定的代价,但日后你得到的,远比付出的多得多。

【Qt编程】基于Qt的词典开发系列九

相关文章:

你感兴趣的文章:

标签云: