QT中QJson库的使用以及json文件的操作

来源:互联网 发布:公司网络管理方案 编辑:程序博客网 时间:2024/05/21 06:39

QJson是Qt中做Json传输的一个类库,可以从我的资源里下载到,QJson的中文主页在这里

下载的时候,强烈建议你用git,从gitorious上下载,而不要用http下载gzip压缩包(因为我下载的版本的gzip压缩包里少pro文件件,而且CMake的配置文件也是错的……)!否则你可能在自己编译的时候走弯路。

QJson的一个例程在这里:

在Qt中如何通过QJson 解析json数据

注意,如果要让例程中的QJson使用中文,而不出乱码,那么,应该把main.cpp的第23-第24行改为:

[cpp] view plaincopy
  1. QString query = "[{\"我的rid\":\"房间号\", \"pid\":\"1000\", \"username\":\"可微\"},{\"rid\":\"000\", \"pid\":\"10200\", \"username\":\"dxy2\"}]";  
  2. QVariant result = parser.parse(query.toUtf8(), &ok);  
也就是把原来的toAscii改成toUtf8~

用C++生成Json字符串(使用时需要#include "Serializer.h"参见:http://www.oschina.net/code/snippet_12_333):

[cpp] view plaincopy
  1. QVariantList people;    
  2.   
  3. QVariantMap bob;  
  4. bob.insert("Name""Bob");  
  5. bob.insert("Phonenumber", 123);  
  6.     
  7. QVariantMap alice;  
  8. alice.insert("Name""Alice");  
  9. alice.insert("Phonenumber", 321);  
  10.   
  11. people << bob << alice;    
  12.   
  13. QJson::Serializer serializer;  
  14. QByteArray json = serializer.serialize(people);   
  15. qDebug() << json;  

输出:

[plain] view plaincopy
  1. "[ { "Name" : "Bob", "Phonenumber" : 123 },  
  2.    { "Name" : "Alice", "Phonenumber" : 321 } ]"  

如果people中含有中文,则serialize之后,会出现乱码,解决方法参见:

http://my3d.sinaapp.com/?p=136

有两种方法:

1、改变Qt的字符编码格式

[cpp] view plaincopy
  1. QTextCodec *codec = QTextCodec::codecForName(“GB18030″);  
  2. QTextCodec::setCodecForLocale(codec);  
  3. QTextCodec::setCodecForCStrings(codec);  
  4. QTextCodec::setCodecForTr(codec);  

2、把serialize的返回值使用Unicode解码

[cpp] view plaincopy
  1. QTextCodec *tc = QTextCodec::codecForName(“UTF-8″);  
  2.   
  3. QJson::Serializer serializer;  
  4. QByteArray json =serializer.serialize(expand);  
  5.   
  6. QString jsonstr=tc->toUnicode(json);  
  7. qDebug()<<"json:"+jsonstr;  

我只试过第二种,确实可行!


第二种方法做的事情比较微妙:

首先,请相信,serialize函数返回的确实是unicode字符,确切的说,是用UTF-8编码的Unicode字符,tc->toUnicode(json)是把用UTF-8编码的json转换成Unicode字符串,这不是多此一举吗?我不可以使用QString(const QByteArray&)构造一个Unicode字符串吗?

有些情况下可以!

看QString(const QByteArray&)的文档描述:

[plain] view plaincopy
  1. QString::QString ( const QByteArray & ba )  
  2.   
  3. Constructs a string initialized with the byte array ba.The given byte array is converted to Unicode using fromAscii(). Stops copying at the first 0 character, otherwise copies the entire byte array.  
  4.   
  5. You can disable this constructor by defining QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example.  
该构造函数会对ba里的内容使用fromAscii()函数解码,fromAscii()是干什么的?如果你碰巧使用QTextCodec::setCodecForCStrings()设置了字符串的编码格式,如QTextCodec::setCodecForCStrings("GB2312")(就像我一样……),那么fromAscii()就会认为ba里的内容是GB2312编码过的,所以fromAscii()函数就是尝试使用GB2312对ba里的内容解码,然后将解码后的内容重新编码为UTF-8格式!错误就这样悄无声息地发生了~

而tc->toUnicode(json)则直接认为json里的内容是UTF-8的(本来就是这样的,不是吗?),让后直接用json里的内容生成字符串,然后就正确了~

结论是:如果你QTextCodec::setCodecForCStrings("UTF-8"),那么QString(const QByteArray&)和tc->toUnicode(json)的效果是一样的;否则QString(const QByteArray&)会产生乱码,tc->toUnicode(json)会返回正确的字符串,不含乱码的那种~

微妙吧~

第一种方法可行的原因是,Unicode是GB18030的一个真子集!就像ASCII是Unicode的一个真子集一样,所以不管用Unicode怎样对ASCII编码解码,总是对的,因为Unicode完美兼容ASCII!


用Json字符串生成C++里的变量(这是本文开始提到的那个例程里的main.cpp里的代码,使用时需要#include "parser.h"):

[cpp] view plaincopy
  1. QJson::Parser parser;  
  2. bool ok;  
  3.   
  4. QString query = "[{\"我的rid\":\"房间号\", \"pid\":\"1000\", \"username\":\"可微\"},{\"rid\":\"000\", \"pid\":\"10200\", \"username\":\"dxy2\"}]";  
  5. QVariant result = parser.parse(query.toUtf8(), &ok);  
  6.   
  7. QVariantList mylist = result.toList();  
  8.   
  9. foreach (QVariant plugin, mylist) {  
  10.     QVariantMap mymap = plugin.toMap();  
  11.     qDebug() << "[" << mymap["我的rid"].toString() << mymap["pid"].toString() << mymap["username"].toString() << "]";  
  12. }