之前一直使用cJSON库进行封装和解析,但随着时间的推移,我发现它的代码实在是太丑陋,也难以维护。因此,我开始研究QT的原生QJson是否能够提供更加优雅的方法来封装一些JSON对象。果然,通过阅读QT的开发文档,我发现QT封装的Json功能非常强大。
在其中,我注意到在qjsonobject.h文件中有如下代码段:
template class Key, class T> class QMap;
typedef QMap QVariantMap;
template class Key, class T> class QHash;
typedef QHash QVariantHash;
上述代码基于模板创建了QMap和QHash两种容器类型。现在,让我们先来介绍一下QMap和QVariantMap的应用,在介绍QVariantMap的应用之前,我们先来了解一下QMap和QVariant。
1、QMap
QMap是Qt库中的一个关联容器,它存储键值对,其中每个键都是唯一的。这使得你可以通过键值来快速查找或访问存储在QMap中的值。
以下是一些QMap的基本操作:
-
插入:使用insert()函数将一个键值对插入到QMap中。 -
获取值:使用value()函数通过键来获取值。 -
查找:使用find()函数查找具有给定键的键值对。 -
删除:使用remove()函数删除具有给定键的键值对。 -
遍历:使用iterator(如QMapIterator或constIterator)遍历QMap中的所有键值对。
下面是一个简单的QMap使用例子:
#include
#include
#include
int main(int argc, char *argv[])
{
QMap map;
map.insert("One", 1);
map.insert("Two", 2);
map.insert("Three", 3);
// 使用value()函数获取值
int one = map.value("One");
qDebug() "one:" ::const_iterator i;
for (i = map.constBegin(); i != map.constEnd(); ++i) {
qDebug() "Key: " ", Value: " return 0;
}
运行结果:
注意,QMap不保证同义词的插入顺序,即如果插入相同的键,第二个插入的键值对将出现在QMap的末尾。如果需要保持插入顺序,可以使用QMap
2、QVariant
QVariant是一个可以存储多种数据类型的类,它可以方便地在不同的函数、类、模块之间传递数据。QVariant的用法非常简单,只需要使用构造函数、赋值操作符、setValue函数等方法将数据存储到QVariant对象中,然后使用toXXX函数将QVariant对象转换为指定类型的数据。例如:
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 存储数据
QVariant v1 = 10; // 存储整数
QVariant v2 = "hello"; // 存储字符串
QVariant v3 = QDateTime::currentDateTime(); // 存储日期时间
// 获取数据
int i = v1.toInt(); // 将 QVariant 转换为整数
QString s = v2.toString(); // 将 QVariant 转换为字符串
QDateTime dt = v3.toDateTime(); // 将 QVariant 转换为日期时间
// 输出数据
qDebug() "v1 = " "v2 = " "v3 = " return a.exec();
}
运行结果:
3、QVariantMap
QT的开发者基于QMap及QVariant的优点,于是开发衍生出了QVariantMap。QVariantMap是一个Qt提供的容器类,它可以存储一组键值对,其中键是QString类型,值是QVariant类型。QVariant是一个可以存储多种数据类型的类,包括基本类型、Qt类型和自定义类型。QVariantMap的优点是可以方便地使用字符串作为键来访问或修改值,而不需要像QMap那样指定键的类型。QVariantMap的缺点是它不能保证键的顺序,也不能存储重复的键。它也有很多应用场景,例如:
-
在QML中,可以使用QVariantMap作为C++和JavaScript之间的数据交换格式,因为它可以自动转换为JavaScript对象。 -
在Qt中,可以使用QVariantMap作为JSON对象的表示方式,因为它可以方便地使用QJsonDocument和QJsonObject进行互相转换。 -
在Qt中,可以使用QVariantMap作为数据库查询的结果集,因为它可以方便地使用QSqlQuery和QSqlRecord进行互相转换。 -
在Qt中,可以使用QVariantMap作为配置文件的存储格式,因为它可以方便地使用QSettings进行读写。
QVariantMap在Json对象转换之间的应用,例如,有一个JsonRpc2.0的请求对象:
{
jsonrpc: "2.0",
id: 1,
method: "Set/LedStatus",
params: {
"color": "blue",
"status": "on"
}
}
编写一个程序封装一个基于JsonRpc2.0的请求对象的方法:
QByteArray JsonRpc2ProcotolPacket(int Id, QString Method, const QVariantMap &_Params)
{
QJsonObject RootObject;
QJsonObject Params = QVariant(_Params).toJsonObject();
RootObject.insert("jsonrpc", "2.0");
RootObject.insert("id", Id);
RootObject.insert("method", Method);
RootObject.insert("params", Params);
QJsonDocument JsonDoc(RootObject);
return JsonDoc.toJson();
}
应用主程序调用:
#include
#include
#include
#include
#include
/*
* Rpc结构
{
jsonrpc: "2.0",
id: 1,
method: "Set/LedStatus",
params: {
"color": "blue",
"status": "on"
}
}
*/
QByteArray JsonRpc2ProcotolPacket(int Id, QString Method, const QVariantMap &_Params)
{
QJsonObject RootObject;
QJsonObject Params = QVariant(_Params).toJsonObject();
RootObject.insert("jsonrpc", "2.0");
RootObject.insert("id", Id);
RootObject.insert("method", Method);
RootObject.insert("params", Params);
QJsonDocument JsonDoc(RootObject);
return JsonDoc.toJson();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//使用QVariantMap封装参数对象部分的数据结构
const QVariantMap &ParamsObject = {
{"color", "blue"},
{"status", "on"}
};
QByteArray JsonStr = JsonRpc2ProcotolPacket(15, "Set/LedStatus", ParamsObject);
qDebug() return a.exec();
}
运行结果:
用起来简直不要太爽!
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !