QT4与JS交互中采用Json字符串
由于QT4没有JSON类,所以采用了开源的qjson库。
1. 编译原代码
需要在QT4下使用,所以采用了QT4进行编译。从http://qjson.sourceforge.net/下载原代码。然后打开QT creator,载入CMAKE文件,进行编译。
编译结果是一个libqjson.dll库文件和一个libqjsond.dll.a文件。
2. 使用
将libqjsond.dll.a文件加入pro文件中,并引入头文件。
将其中一个例子代码拷贝到项目中。
#include "mainwindow.h" #include <QTextCodec> #include <QApplication> #include <QJson/Parser> #include <QJson/QObjectHelper> #include <QJson/Serializer> #include <QDebug> void parseJson() { QString json="{\"encoding\" : \"UTF-8\",\ \"plug-ins\" : [\ \"python\",\ \"c++\",\ \"ruby\"\ \],\ \"indent\" : { \"length\" : 3, \"use_space\" : true }\ }"; QByteArray ba = json.toUtf8(); QJson::Parser parser; bool ok; QVariantMap result = parser.parse (ba, &ok).toMap(); if (!ok) { qFatal("An error occured during parsing"); exit (1); } qDebug() << "encoding:" << result["encoding"].toString(); qDebug() << "plugins:"; foreach (QVariant plugin, result["plug-ins"].toList()) { qDebug() << "\t-" << plugin.toString(); } QVariantMap nestedMap = result["indent"].toMap(); qDebug() << "length:" << nestedMap["length"].toInt(); qDebug() << "use_space:" << nestedMap["use_space"].toBool(); } int main(int argc, char *argv[]) { QApplication a(argc, argv); //防止页面出现乱码 parseJson(); QTextCodec *codec = QTextCodec::codecForName("GBK"); QTextCodec::setCodecForLocale(codec); QTextCodec::setCodecForCStrings(codec); QTextCodec::setCodecForTr(codec); MainWindow w; w.showMaximized(); return a.exec(); }
运行正常,一切OK。
3. 与JS的交互
应用场景是QT通过QWebKit与html页面通信。为了简化通信接口,决定采用JSON在JS与C++之间进行数据传输。
(1)JS端的代码用于拼接JSON字符串
delete_user:function() { if(mt_select_ids.length == 0) { alert("请点击左侧的复选按键选择用户......"); return; } var all = true; var json = "{\"users\":["; for(j = 0, len = mt_select_ids.length; j < len; j++) { json += "{\"userid\":\""; json += mt_select_ids[j].userid; json += "\",\"level\":\""; json += mt_select_ids[j].level; json += "\"},"; } json = json.slice(0, json.length - 1); //去掉最后的逗号 json += "]}"; var re = window.secTool.deliverData(USERACTION["EDIT"], EDIT_ACTION["EDIT_DELETE"], json); var sel = JSON.stringify(re); //alert(sel); if(sel == 'false') { mytable.$refs.articleTable.clearSelection(); return; } mytable.$refs.articleTable.clearSelection(); mtdata.splice(0, mtdata.length); window.secTool.deliverData(USERACTION["DISPLAY"], disp_level, ""); if(!all) alert("执行完成,部分用户已不能降级!"); }
其中调用的C++接口为window.secTool.deliverData, 前两个参数给出了事件和数据类型,最后一个参数是JSON串。
(2)QT C++对JS数据的处理
bool UserManager::deliverData(QString action, QString datatype, QString json) { bool suc = true; USERACTION act = (USERACTION)action.toInt(); int intype = datatype.toInt(); curDisplay = (DISPLAY_ACTION)intype; if(act == DISPLAY) { DISPLAY_ACTION type = (DISPLAY_ACTION)datatype.toInt(); std::map<QString, UserInfo>::iterator it; for(it = Utility::userList.begin(); it != Utility::userList.end(); it++) { UserInfo info = it->second; if(type == DISPLAY_ALL || intype == (info.level + 1)) { QString slevel; if(info.level == SUPERVIOR) slevel = "系统级"; else if(info.level == DESIGNER) slevel = "开发级"; else slevel = "使用级"; QString addrow = QString("var row = {userid:\'%1\',name:\'%2\',unit:\'%3\',level:\'%4\',pid:\'%5\',phone:\'%6\'}; mtdata.push(row);"). arg(info.id, info.name, info.unit, slevel, info.passportId, info.phone); page()->mainFrame()->evaluateJavaScript(addrow); } } } else { QVariantMap result; if(json.size()) { QByteArray ba = json.toUtf8(); QJson::Parser parser; bool ok; result = parser.parse (ba, &ok).toMap(); if (!ok) { qDebug() << "An error occured during parsing at UserManager::deliverData" << endl; return false; } } EDIT_ACTION type = (EDIT_ACTION)datatype.toInt(); switch(type) { case EDIT_ADDNEW: { AddUserDialog dlg(this); dlg.exec(); } break; case EDIT_RAISE: { foreach (QVariant user, result["users"].toList()) { QVariantMap selectUser = user.value<QVariantMap>(); QString userid = list["userid"].toString(); std::map<QString, UserInfo>::iterator it = Utility::userList.find(userid); if(it != Utility::userList.end()) { if(it->second.level == DESIGNER) { it->second.level = SUPERVIOR; } else { if(it->second.level == UTILITY) it->second.level = DESIGNER; } } } } break; case EDIT_LOWER: { foreach (QVariant user, result["users"].toList()) { QVariantMap list = user.value<QVariantMap>(); QString userid = list["userid"].toString(); std::map<QString, UserInfo>::iterator it = Utility::userList.find(userid); if(it != Utility::userList.end()) { if(it->second.level == SUPERVIOR ) { it->second.level = DESIGNER; } else { if(it->second.level == DESIGNER) it->second.level = UTILITY; } } } } break; case EDIT_DELETE: { int sel = QMessageBox::critical(this, "删除警告", "此操作将使用户无法再使用本软件,是否确定删除?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(sel == QMessageBox::No) return false; foreach (QVariant user, result["users"].toList()) { QVariantMap selectUser = user.value<QVariantMap>(); QString userid = selectUser["userid"].toString(); std::map<QString, UserInfo>::iterator it = Utility::userList.find(userid); if(it != Utility::userList.end()) { Utility::userList.erase(it); } } } break; } } //保存数据 return suc; }
可以看出,qjson是通过QVariant和QVariantMap数据类型作为JSON的载体,它将每个域存入一个QVariant中,多个域构成QVariantMap。对于复杂类型每个QVariant是也可以包含QVariantMap。所以处理时要注意。