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。所以处理时要注意。

 

posted @ 2021-01-14 17:39  小船1968  阅读(689)  评论(0编辑  收藏  举报