QT中有解析Json的一个类叫QScript。貌似还有一个QJson,但听说解析的方便性不如QScript,具体没有深入探究,这里仅简单记录一下QScript的使用。

首先,主要使用到的类有QScriptEngine和QScriptValue,这里写了一个Demo,是用来将一个存有Json语句的QString解析后存入XML里并在Debug里显示出来。由于理论知识装备的并不充足,所以就先实战一下吧。写入XML方法使用的是QXmlStreamWriter类。

首先,建议使用窗口,即使是空窗口。因为这样当你关闭窗口的时候程序就会自动结束。那使用如下代码呢?

1
2
3
4
5
6
int main(int argc, char *argv[]){
    dbg<<"This is a Test !";
    QScriptJson qsj("D:\\json.xml");//QScriptJson是接下来自己定义的类
    qsj.write2File();
    return 0;
}

NO !会出现下面的错误信息:

QScriptEngine: Must construct a Q(Core)Application before a QScriptEngine

意思就是要使用QScriptEngine,必须要先构造一个Q(Core)Application,所以老老实实构造一个吧。

下面是我的程序代码:

【AHeaders.h】加上了要使用的头文件

1
2
3
4
5
6
7
8
9
10
11
#ifndef AHEADERS_H
#define AHEADERS_H
 
#include <QDebug>
#include <QVariant>
#include <QString>
#include <QStringList>
#include <QXmlStreamWriter>
#define dbg qDebug()
 
#endif // AHEADERS_H

【qscriptjson.h】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef QSCRIPTJSON_H
#define QSCRIPTJSON_H
 
#include <QScriptEngine>
#include <QScriptValue>
#include <QScriptValueIterator>
#include <QFile>
#include <QMap>
#include "AHeaders.h"
 
class QScriptJson
{
public:
   QScriptJson(const QString &fileName);
   ~QScriptJson();
 
   bool write2File();
private:
   void getPropety(QScriptValue sv, QStringList sLsPty);//输出到XML
   void getPropety(QScriptValue sv, QStringList sLsPty,QString space);//输出到Debug
private:
   QXmlStreamWriter m_writer;
   QString m_fileName;
   QMap<QString,QVariant> m_mapProperty; //存放数据层次属性
   QMap<QString,QVariant> m_mapItems;   //节点中的子节点集
};
 
#endif // QSCRIPTJSON_H

【qscriptjson.cpp】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "qscriptjson.h"
//要处理的数据
static QString datas =
        QString("{'billcount':2,'bills':[\
         {'billID':'010101001','billname':'平整场地','billunit':'m2','decount':3,\
            'des':[{'deID':'A1-1','decont':'建筑场地挖填高度在±30cm以内的找平','dename':'平整场地','deunit':'100m2'},\
                {'deID':'A1-3','decont':'土方开挖','dename':'人工挖土方 三类土 深度在1.5m内','deunit':'100m3'},\
                {'deID':'A1-4','decont':'土方开挖','dename':'人工挖土方 四类土 深度在1.5m内','deunit':'100m3'}]},\
        {'billID':'010101005','billname':'挖淤泥、流砂','billunit':'m3','decount':1,\
            'des':[{'deID':'A1-27','decont':'挖淤泥、流砂','dename':'人工挖淤泥流砂','deunit':'100m3'}]}]}");
 
QScriptJson::QScriptJson(const QString &fileName)
{
    m_fileName=fileName;
    QStringList sls;
    m_mapProperty.insert("_BEGIN_","BillTable");
    sls<<"billcount"<<"bills";
    m_mapProperty.insert("BillTable",sls);
    sls.clear();
    sls<<"billID"<<"billname"<<"billunit"<<"decount"<<"des";
    m_mapProperty.insert("bills",sls);
    sls.clear();
    sls<<"deID"<<"decont"<<"dename"<<"deunit";
    m_mapProperty.insert("des",sls);
    sls.clear();
    m_mapProperty.insert("_END_","_END_");
 
    m_mapItems.insert("bills","BillItem");
    m_mapItems.insert("des","DesItem");
 
}
 
QScriptJson::~QScriptJson()
{
 
}
 
bool QScriptJson::write2File()
{
    QString dt=datas;
    QFile file(m_fileName);
    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        dbg<<QString("打不开文件 : %1").arg (m_fileName);
        return false;
    }
    try{
        m_writer.setDevice(&file);
        m_writer.setAutoFormatting(true);
        //文档开始
        m_writer.writeStartDocument();
 
        QScriptEngine engine;
        QScriptValue sv = engine.evaluate("value="+dt);
        QString strBegin=m_mapProperty.value("_BEGIN_").toString();
 
        m_writer.writeStartElement(strBegin);
        QStringList sLsPty=m_mapProperty.value(strBegin).toStringList();
        getPropety(sv,sLsPty," ");
        getPropety(sv,sLsPty);
        m_writer.writeEndElement();
        m_writer.writeEndDocument();
    }catch(...){
         dbg<<"Error: Write to File .";
         file.close();
    }
    file.close();
}
 
void QScriptJson::getPropety(QScriptValue sv,QStringList sLsPty)
{
    foreach(QString element,sLsPty){
        QScriptValue sptV=sv.property(element);
        if(!sptV.isArray()){
            QString value=sptV.toString();
            m_writer.writeAttribute(element,value);
        }else{
            m_writer.writeStartElement(element);
 
            QScriptValueIterator it(sptV);
            while (it.hasNext()) {
                it.next();               
                if(it.flags()&&QScriptValue::SkipInEnumeration)continue;
                QString item=m_mapItems.value(element).toString();
                m_writer.writeStartElement(item);
                QStringList sLs_Child=m_mapProperty.value(element).toStringList();
                getPropety(it.value(),sLs_Child);
                m_writer.writeEndElement();
            }
            m_writer.writeEndElement();
        }
    }
}
 
void QScriptJson::getPropety(QScriptValue sv, QStringList sLsPty,QString space)
{
    foreach(QString str,sLsPty){
        QScriptValue sptV=sv.property(str);
        if(!sptV.isArray()){
            QString str2=sptV.toString();
            dbg<<(space+str+QString(" : ")+str2);  //如果当前属性不是一个数组,则输出其内容
        }else{
            dbg<<(space+str+QString(" [ "));
            QScriptValueIterator it(sptV);
//            dbg<<it.name()<<it.value().toString();
//            if(it.hasNext())it.next();
            while (it.hasNext()) {
                it.next();
//                dbg<<it.name()<<it.value().toString();
                if(it.flags()&&QScriptValue::SkipInEnumeration)continue;
                QStringList sLs_Child=m_mapProperty.value(str).toStringList();
                getPropety(it.value(),sLs_Child,space+"   ");
//                it.next();
            }
//            dbg<<it.name()<<it.value().toString();
            dbg<<(space+str+QString(" ] "));
        }
    }
}

至此,主要文件结束,下面是一个窗口文件:

【mainwindow.h】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QTextEdit>
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QString strText, QWidget *parent = 0);
    ~MainWindow();
    void setText(QString strText);
private:
    QTextEdit *m_te;
    QString m_text;
};
 
#endif // MAINWINDOW_H

【mainwindow.cpp】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "mainwindow.h"
 
 
MainWindow::MainWindow(QString strText,QWidget *parent)
    : QMainWindow(parent)
{
   m_text=strText;
   m_te=new QTextEdit(this);
   m_te->setText(m_text);
   this->setCentralWidget(m_te);
}
 
MainWindow::~MainWindow()
{
    delete m_te;
}
 
void MainWindow::setText(QString strText)
{
    m_text=m_text+"\n"+strText;
    m_te->setText(m_text);
}

最后上Main函数!

【main.cpp】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "mainwindow.h"
#include <QApplication>
#include "qscriptjson.h"
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w("程序开始。。。");
    w.show();
 
    dbg<<"This is a Test !";
    QScriptJson qsj("D:\\json.xml");
    qsj.write2File();
 
    w.setText("程序已运行完成!\n\n关闭窗口退出程序。。。");
    return a.exec();
}

运行后生成的XML文档“json.xml”如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<BillTable billcount="2">
    <bills>
        <BillItem billID="010101001" billname="平整场地" billunit="m2" decount="3">
            <des>
                <DesItem deID="A1-1" decont="建筑场地挖填高度在±30cm以内的找平" dename="平整场地" deunit="100m2"/>
                <DesItem deID="A1-3" decont="土方开挖" dename="人工挖土方 三类土 深度在1.5m内" deunit="100m3"/>
                <DesItem deID="A1-4" decont="土方开挖" dename="人工挖土方 四类土 深度在1.5m内" deunit="100m3"/>
            </des>
        </BillItem>
        <BillItem billID="010101005" billname="挖淤泥、流砂" billunit="m3" decount="1">
            <des>
                <DesItem deID="A1-27" decont="挖淤泥、流砂" dename="人工挖淤泥流砂" deunit="100m3"/>
            </des>
        </BillItem>
    </bills>
</BillTable>

Debug输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
This is a Test !
" billcount : 2"
" bills [ "
"    billID : 010101001"
"    billname : 平整场地"
"    billunit : m2"
"    decount : 3"
"    des [ "
"       deID : A1-1"
"       decont : 建筑场地挖填高度在±30cm以内的找平"
"       dename : 平整场地"
"       deunit : 100m2"
"       deID : A1-3"
"       decont : 土方开挖"
"       dename : 人工挖土方 三类土 深度在1.5m内"
"       deunit : 100m3"
"       deID : A1-4"
"       decont : 土方开挖"
"       dename : 人工挖土方 四类土 深度在1.5m内"
"       deunit : 100m3"
"    des ] "
"    billID : 010101005"
"    billname : 挖淤泥、流砂"
"    billunit : m3"
"    decount : 1"
"    des [ "
"       deID : A1-27"
"       decont : 挖淤泥、流砂"
"       dename : 人工挖淤泥流砂"
"       deunit : 100m3"
"    des ] "
" bills ] "

接下来要研读研读理论方面的内容了。博文中有错误之处,欢迎指正!

声明:本博文为博主原创,转载请注明来源,谢谢合作!

QT学习之QScript的更多相关文章

  1. QT学习第1天

    QT学习第一天  坚持住!! 一 Qt概述 1.Qt发展历史 (1)1991年诞生(Haavard Nord/Eirik Chambe-Eng), (2)1994年创立Troll Tech(奇趣科技) ...

  2. 【转载】分享一些Qt学习资源,欢迎下载

    资源来源:http://bbs.csdn.net/topics/390358737 经过我一翻整理,把一些我收集到的Qt学习资源分享给大家,主要适合新手,老鸟可以直接忽略我.要说明一下,很多资源都是在 ...

  3. QT学习之路--创建一个对话框

    Q_OBJECT:这是一个宏,凡是定义信号槽的类都必须声明这个宏. 函数tr()全名是QObject::tr(),被他处理过的字符串可以使用工具提取出来翻译成其他语言,也就是做国际化使用. 对于QT学 ...

  4. 转载: Qt 学习之路 2归档

    Qt 学习之路 2归档 http://www.devbean.net/2012/08/qt-study-road-2-catelog/

  5. Qt 学习资料

    Qter开源社区http://www.qter.org/ [Qt教程], 作者yafeilinux [视频] QT学习之路:从入门到精通 <C++ Qt 编程视频教程>

  6. qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果

    应大家的要求,还是把完整的project文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm 先看看执行效果,我用的群创7寸屏 ...

  7. Qt学习博客推荐

    附录C Qt资源 C.1 Qt 官方资源 全 球各大公司以及独立开发人员每天都在加入 Qt 的开发社区.他们已经认识到了Qt 的架构本身便可加快应用程序开发进度.这些开发人员,无论是想开发单平台软件. ...

  8. qt学习教程1.qt开发环境搭建

    qt学习教程1.qt开发环境搭建 首先下载qt 下载地址:http://download.qt.io/archive/qt/ 此教程使用的版本为5.1.1 下载好后,打开安装包,然后点下一步 选择一个 ...

  9. QT学习教程

    原地址:http://www.devbean.NET/2012/08/qt-study-road-2-catelog/ 网上看到的不错的教程 本教程以qt5为主,部分地方会涉及qt4.据说非常适合qt ...

随机推荐

  1. iOS如何实时查看App运行日志

    Linux下管理挂载IOS设备——libimobiledevicehttps://www.jianshu.com/p/6423610d3293https://blog.csdn.net/fengzei ...

  2. hive 全表全字段对比

    select * from ( select max(t1.source) as source ,t1.c1 ,t1.c2 ,t1.c3 ,count(*) as cnt from ( as sour ...

  3. HikariPool连接池的使用

    HikariDataSource datasource= new HikariDataSource( xxxx ); Connection cn = datasource.getConnection( ...

  4. sofa-boot(1)helloworld项目

    本示例参考:https://www.sofastack.tech/sofa-boot/docs/QuickStart 示例采用sofa-boot 3.1.1版本. 如下步骤: 1.进入https:// ...

  5. Python报错:UnicodeEncodeError 'gbk' codec can't encode character

    今天在使用Python文件处理写网络上爬取的文件的时候,遇到了错误:UnicodeEncodeError: ‘gbk’ codec can’t encode character ‘\xa0’ in p ...

  6. my09_mysql指定时间点恢复之binlog start-position

    场景描述 ********************************************* 在远程服务器做的全备并已经恢复,同时使用binlog server备份binlog 之后,删除了库 ...

  7. vue 子组件调用父组件的函数

    子组件调用父组件的函数,使用$emit(eventName,[...args]),触发当前实例上的事件.附加参数都会传给监听器回调. 子组件 <template> <div> ...

  8. element-ui表单验证(电话,邮箱)

    element-ui Form表单验证 最近刚好使用了element-ui的form表单,官网只提供的示例,这里把一些常用的验证记录下来,方便后期查找最终的效果是这样的, 这个表单里还加入了一下其他组 ...

  9. OS---外存分配方式

    1.概述 1.1 在为文件分配外存空间时,所考虑的主要问题:如何有效利用外存空间?如何提高对文件的访问速度? 1.2 常用的外存分配方法:连续分配.链接分配.索引分配(在一个系统中,仅采用一种分配方式 ...

  10. team foundation server 工具的使用

    1.打开TFS工具点击创建集合,填写集合名称,下一步,按照步骤一步一步的往下操作. 2.创建完集合以后,打开VS工具,如下图,在主页上左键选择新建团队项目. 3.选择团队项目,然后选择新建的项目集合和 ...