Qt jsoncpp 对象拷贝、删除、函数调用 demo

简介: /***************************************************************************************************** * Qt jsoncpp 对象拷贝、删除、函数调用 demo * 声明: * 本程序主要就是为了验证jsoncpp中Json::Value对象中的append、等号赋值是拷贝内容,还是赋值指针, * 就测试而言,从目前的情况来看应该是拷贝内容,代码得以验证。
/*****************************************************************************************************
 *                       Qt jsoncpp 对象拷贝、删除、函数调用 demo
 * 声明:
 *     本程序主要就是为了验证jsoncpp中Json::Value对象中的append、等号赋值是拷贝内容,还是赋值指针,
 * 就测试而言,从目前的情况来看应该是拷贝内容,代码得以验证。
 *
 *                                              2015-11-15 晴 深圳 南山平山村  曾剑锋
 ****************************************************************************************************/


/**
 * 参考文档:
 *    1. JsonCpp ambiguous overload only in Windows
 *        http://stackoverflow.com/questions/18901781/jsoncpp-ambiguous-overload-only-in-windows
 *    2. QT 使用jsoncpp
 *        http://www.cnblogs.com/foxhengxing/archive/2011/12/02/2272020.html
 *    3. Using JsonCpp and Qt Together (Problems with Unicode)
 *        http://stackoverflow.com/questions/4191528/using-jsoncpp-and-qt-together-problems-with-unicode
 *    4. ambiguous overload for 'operator[]'
 *        http://www.gamedev.net/topic/618752-ambiguous-overload-for-operator/
 *    5. 一个C++编译错误 
 *        http://blog.chinaunix.net/uid-7865778-id-2038882.html
 */


#include <QCoreApplication>
#include "json/json.h"
#include <QString>
#include <QFile>
#include <QDebug>

#define ICON_PATH   "apps\/images\/"
#define SHELL_PATH  "\/usr\/share\/web\/lighttpd\/webpages\/shell\/"
#define JSON_FILE   "F:\/QT\/json.txt"

void jsonUpdateApp(Json::Value *programs, int index, QString icon, QString exec) {

    // 名字相同了,自然不需要再重新赋值了
    //(*programs)[index]["Name"]   = name.toStdString();
    (*programs)[index]["Icon"]     = QString(ICON_PATH).append(icon).toStdString();
    (*programs)[index]["Exec"]     = QString(SHELL_PATH) .append(exec).append(".sh").toStdString();

}

void jsonAddApp(Json::Value *programs, QString name, QString icon, QString exec) {

    // 合成新的数据并加入json对象中
    Json::Value item;
    item["Name"]                = name.toStdString();
    item["Order"]               = 999;
    item["Icon"]                = QString(ICON_PATH).append(icon).toStdString();
    item["Type"]                = "application";
    item["Exec"]                = QString(SHELL_PATH).append(exec).append(".sh").toStdString();
    item["ProgramType"]         = "gui";
    item["Description_Link"]    = -1;
    item["Lock"]                = -1;

    programs->append(item);

}

void copyItem(Json::Value *programs, Json::Value *newPrograms, int index) {

    // 合成新的数据并加入json对象中
    Json::Value newItem;
    newItem["Name"]                 = (*programs)[index]["Name"];
    newItem["Order"]                = (*programs)[index]["Order"];
    newItem["Icon"]                 = (*programs)[index]["Icon"];
    newItem["Type"]                 = (*programs)[index]["Type"];
    newItem["Exec"]                 = (*programs)[index]["Exec"];
    newItem["ProgramType"]          = (*programs)[index]["ProgramType"];
    newItem["Description_Link"]     = (*programs)[index]["Description_Link"];
    newItem["Lock"]                 = (*programs)[index]["Lock"];

    newPrograms->append(newItem);

}

bool checkAndAddUpdateAppByName(Json::Value *oldRoot, Json::Value *newRoot, QString name,
        QString icon, QString exec) {

    bool ret             = false;
    Json::Value programs = ((*oldRoot)["main_menu"])["apps"];
    Json::Value newPrograms;

    int i = 0;
    for ( i = 0; i < programs.size(); i++ ) {

        // 如果有name对应的app,那么就对app进行更新
        if ( QString::fromStdString(programs[i]["Name"].asString()).trimmed().compare(name.trimmed()) == 0 ) {
            jsonUpdateApp(&programs, i, icon, exec);
            ret = true;
        }

        copyItem(&programs, &newPrograms, i);
    }

    // 如果name没有重复的,那么添加一个这个app
    if ( i >= programs.size() )
        jsonAddApp(&newPrograms, name, icon, exec);

    Json::Value newApps;
    newApps["apps"]         = newPrograms;
    (*newRoot)["main_menu"] = newApps;

    return ret;
}

bool checkAndRemoveAppName(Json::Value *oldRoot, Json::Value *newRoot, QString name) {

    bool ret             = false;
    Json::Value programs = ((*oldRoot)["main_menu"])["apps"];
    Json::Value newPrograms;

    int i = 0;
    for ( i = 0; i < programs.size(); i++ ) {

        if ( QString::fromStdString(programs[i]["Name"].asString()).trimmed().compare(name.trimmed()) == 0 ) {
            ret = true;
            continue;
        }

        /*
         * // 合成新的数据并加入json对象中
         * Json::Value newItem;
         * newItem["Name"]                = programs[i]["Name"];
         * newItem["Order"]               = programs[i]["Order"];
         * newItem["Icon"]                = programs[i]["Icon"];
         * newItem["Type"]                = programs[i]["Type"];
         * newItem["Exec"]                = programs[i]["Exec"];
         * newItem["ProgramType"]         = programs[i]["ProgramType"];
         * newItem["Description_Link"]    = programs[i]["Description_Link"];
         * newItem["Lock"]                = programs[i]["Lock"];
         * 
         * newPrograms.append(newItem);
         *
         * 下面这个函数是从上面的代码中重构出来的
         */
        copyItem(&programs, &newPrograms, i);
    }

    Json::Value newApps;
    newApps["apps"]         = newPrograms;
    (*newRoot)["main_menu"] = newApps;

    return ret;
}

int main(int argc, char *argv[])
{

    QCoreApplication a(argc, argv);

    // 检查文件是否存在
    QFile jsonFileObject("F:/QT/json.txt");
    if ( !jsonFileObject.exists() ) {
        qDebug() << "Please check json.txt file already exist." << endl;
        return -1;
    }

    // 打开并读取文件
    QString jsonString;
    if ( jsonFileObject.open(QIODevice::ReadOnly | QIODevice::Text) ) {
        jsonString.append(jsonFileObject.readAll());
        jsonFileObject.close();
    } else {
        qDebug() << "Open json file failt." << endl;
        return -1;
    }

    // 解析json数据
    Json::Value root;
    Json::Reader reader;
    bool parsingSuccessful = reader.parse(jsonString.toStdString(), root);
    if ( !parsingSuccessful ) {
        qDebug() << "Failed to parse configure.\n ";
        return -1;
    }

    // 测试获取json数据
    Json::Value programs = root["main_menu"]["apps"];
    qDebug() << "programs size: " << programs.size();
    // 这里的获取数据数据索引后面一定要加一个小写的u,目前还不知道具体的原因
    std::cout << "Exec: " << programs[0u]["Exec"].asString() << std::endl;

    Json::Value outRootWithRemove;
    checkAndRemoveAppName(&root, &outRootWithRemove, "Network");
    Json::Value outRootWithRemoveAndAdd;
    checkAndAddUpdateAppByName(&outRootWithRemove, &outRootWithRemoveAndAdd, "zengjf", "zengjf", "zengjf");

    // 生成写入文件的字符串
    Json::StyledWriter writer;
    std::string outputJsonstring = writer.write(outRootWithRemoveAndAdd);

    // 将输出字符串输出到console上查看效果
    std::cout << outputJsonstring << std::endl;

    // 如果仅仅是测试,不需要写入文件,省的每次还要去换json.txt文件
    if ( jsonFileObject.open(QIODevice::WriteOnly | QIODevice::Text) ) {
        jsonFileObject.write(outputJsonstring.data());
        jsonFileObject.close();
    } else {
        qDebug() << "Open json file failt." << endl;
        return -1;
    }

    return a.exec();
}


/**
  * json.txt
  * {
  *    "main_menu" : {
  *       "apps" : [
  *          {
  *             "Description_Link" : -1,
  *             "Exec" : "/usr/share/web/lighttpd/webpages/shell/browser.sh http://processors.wiki.ti.com",
  *             "Icon" : "apps/images/web-icon.png",
  *             "Lock" : -1,
  *             "Name" : "Browser",
  *             "Order" : 999,
  *             "ProgramType" : "gui",
  *             "Type" : "application"
  *          },
  *          {
  *             "Description_Link" : -1,
  *             "Exec" : "/usr/share/web/lighttpd/webpages/shell/network.sh",
  *             "Icon" : "apps/images/network-icon.png",
  *             "Lock" : -1,
  *             "Name" : "Network",
  *             "Order" : 999,
  *             "ProgramType" : "gui",
  *             "Type" : "application"
  *          }
  *     ]
  * }
  */


/**
  * 输出结果:
  * json.txt
  * {
  *    "main_menu" : {
  *       "apps" : [
  *          {
  *             "Description_Link" : -1,
  *             "Exec" : "/usr/share/web/lighttpd/webpages/shell/browser.sh http://processors.wiki.ti.com",
  *             "Icon" : "apps/images/web-icon.png",
  *             "Lock" : -1,
  *             "Name" : "Browser",
  *             "Order" : 999,
  *             "ProgramType" : "gui",
  *             "Type" : "application"
  *          },
  *          {
  *             "Description_Link" : -1,
  *             "Exec" : "/usr/share/web/lighttpd/webpages/shell/zengjf.sh",
  *             "Icon" : "apps/images/zengjf",
  *             "Lock" : -1,
  *             "Name" : "zengjf",
  *             "Order" : 999,
  *             "ProgramType" : "gui",
  *             "Type" : "application"
  *          }
  *     ]
  * }
  */

 

目录
相关文章
|
4月前
|
Linux 数据处理 C++
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(一)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
200 0
|
4月前
|
程序员
QT 官方QObject对象翻译要点(纯属个人翻译,不靠谱)
QT 官方QObject对象翻译要点(纯属个人翻译,不靠谱)
56 1
|
4月前
|
存储 Linux API
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(三)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
94 1
|
4月前
|
消息中间件 Linux 数据处理
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(二)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
121 1
|
11月前
|
C++
Qt 父子对象的关系
Qt 父子对象的关系
73 0
|
2月前
|
C++
基于QT实现的拷贝文件以及实时进度条(简易版)
1.基于按钮或者菜单栏的槽里去写逻辑函数(我这边用的是菜单栏),ui实现的进度条 2.创建两个对象,一个是源文件,一个是目标文件分别用getopenfileName、getsavefileName函数即可。 3.利用QFile类去实现对两个文件的创建,因为QFile中可以获取文件的属性已经读写等。 4.循环的去读取源文件中的数据,然后写入目标文件
264 6
|
7天前
|
设计模式 前端开发 安全
Qt注册类对象单例与单类型区别
在进行开发时,应当根据具体的应用场景和需求来选择使用单例模式或是单类型。如果是全局服务或状态管理,可能需要单例模式;如果是为了使QML环境下的不同组件能够访问到同一个后端服务对象,则可能需要使用单类型。
15 2
|
3月前
|
编译器 C++
(10)Qt对象模型
(10)Qt对象模型
|
3月前
|
前端开发
自定义QT QWidget对象响应弹出菜单的解决方法
自定义QT QWidget对象响应弹出菜单的解决方法
51 1
|
4月前
|
Java 程序员 测试技术
【Qt底层之内存管理机制】Qt 对象 父子关系、运行时机制与高效编程技巧
【Qt底层之内存管理机制】Qt 对象 父子关系、运行时机制与高效编程技巧
291 2