Qt5中自定义类与JSON的转换:完整指南**
在现代软件开发中,JSON(JavaScript Object Notation)因其轻量级、易读易写以及与JavaScript的良好兼容性,成为了数据交换的常用格式,在使用Qt5进行跨平台开发时,经常需要将自定义的类对象序列化为JSON字符串以便存储或传输,或者将JSON字符串反序列化为类对象,本文将详细介绍在Qt5中如何实现自定义类到JSON的转换,以及从JSON转换回自定义类。
Qt5提供了QJsonDocument、QJsonObject、QJsonArray和QJsonValue等类来处理JSON数据,要将自定义类转换为JSON,核心思想是将类的各个属性(成员变量)映射到JSON对象的键值对中。
准备工作:包含必要的头文件
在使用Qt的JSON功能之前,确保你的项目文件(.pro)中包含了core模块:
QT += core
然后在源文件中包含必要的头文件:
#include <QJsonObject> #include <QJsonDocument> #include <QJsonArray> #include <QVariant> #include <QDebug>
将自定义类转换为JSON
要将自定义类转换为JSON,通常需要为该类编写一个或两个辅助函数:
- 一个将类对象转换为
QJsonObject的函数。 - (可选)一个将类对象直接转换为JSON字符串的函数。
假设我们有一个简单的Person类:
#include <QString>
#include <QJsonObject>
class Person
{
public:
Person(const QString &name = "", int age = 0, const QString &email = "");
QString getName() const;
int getAge() const;
QString getEmail() const;
// 将Person对象转换为QJsonObject
QJsonObject toJson() const;
// 从QJsonObject创建Person对象(静态工厂方法,用于反序列化)
static Person fromJson(const QJsonObject &json);
private:
QString m_name;
int m_age;
QString m_email;
};
// 构造函数实现
Person::Person(const QString &name, int age, const QString &email)
: m_name(name), m_age(age), m_email(email) {}
QString Person::getName() const { return m_name; }
int Person::getAge() const { return m_age; }
QString Person::getEmail() const { return m_email; }
1 实现toJson()函数
这个函数负责将Person类的各个成员变量填充到QJsonObject中:
QJsonObject Person::toJson() const
{
QJsonObject json;
json["name"] = m_name; // QString可以直接赋值给QJsonValue
json["age"] = m_age; // int等基本类型也会自动转换
json["email"] = m_email;
return json;
}
2 转换为JSON字符串
有了QJsonObject后,可以轻松地将其转换为JSON字符串:
QString Person::toJsonString() const
{
QJsonObject jsonObj = this->toJson();
QJsonDocument jsonDoc(jsonObj);
// 如果需要紧凑格式的字符串,使用 QJsonDocument::Compact
// 如果需要格式化的(带缩进)字符串,使用 QJsonDocument::Indented
return jsonDoc.toJson(QJsonDocument::Indented);
}
使用示例:
int main()
{
Person person("张三", 30, "zhangsan@example.com");
QString jsonString = person.toJsonString();
qDebug() << "Person JSON:" << jsonString;
return 0;
}
输出可能类似于:
Person JSON: "{\n \"age\": 30,\n \"email\": \"zhangsan@example.com\",\n \"name\": \"张三\"\n}"
将JSON转换回自定义类
反序列化过程是将JSON字符串或QJsonObject还原为自定义类对象,通常我们会实现一个静态的fromJson方法。
1 实现fromJson(const QJsonObject &json)函数
这个函数接收一个QJsonObject,从中提取数据并构造类对象:
Person Person::fromJson(const QJsonObject &json)
{
Person person;
if (json.contains("name") && json["name"].isString()) {
person.m_name = json["name"].toString();
}
if (json.contains("age") && json["age"].isDouble()) { // isDouble() 因为数字在JSON中默认是double
person.m_age = json["age"].toInt(); // 使用toInt()转换为int
}
if (json.contains("email") && json["email"].isString()) {
person.m_email = json["email"].toString();
}
return person;
}
重要提示:
- 在访问JSON对象中的值之前,最好使用
contains()方法检查键是否存在。 - 使用
isString(),isDouble(),isArray(),isObject()等方法检查值的类型,避免类型不匹配导致的错误。 - 对于数字类型,JSON默认使用
double,如果需要int或qint64,可以使用toInt(),toLong()等方法进行转换。
2 从JSON字符串转换
如果有一个JSON字符串,可以先将其解析为QJsonDocument,再获取QJsonObject,然后调用fromJson:
Person Person::fromJsonString(const QString &jsonString)
{
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
if (jsonDoc.isNull() || !jsonDoc.isObject()) {
qDebug() << "Failed to parse JSON string or not an object";
return Person(); // 返回默认构造的对象或抛出异常
}
QJsonObject jsonObj = jsonDoc.object();
return Person::fromJson(jsonObj);
}
使用示例:
int main()
{
QString jsonString = R"({
"name": "李四",
"age": 25,
"email": "lisi@example.com"
})";
Person person = Person::fromJsonString(jsonString);
qDebug() << "Name:" << person.getName()
<< "Age:" << person.getAge()
<< "Email:" << person.getEmail();
return 0;
}
输出:
Name: "李四" Age: 25 Email: "lisi@example.com"
处理更复杂的类(嵌套对象与数组)
如果类的成员变量是另一个自定义类对象,或者是一个列表/数组,处理方式会略有不同。
1 嵌套对象
假设Person类有一个Address成员:
class Address
{
public:
Address(const QString &city = "", const QString &street = "");
QString getCity() const;
QString getStreet() const;
QJsonObject toJson() const;
static Address fromJson(const QJsonObject &json);
private:
QString m_city;
QString m_street;
};
// Address的toJson和fromJson实现类似Person
// ...
修改Person类:
class Person
{
// ... 其他成员和方法
Address m_address;
// ...
QJsonObject toJson() const override;
static Person fromJson(const QJsonObject &json) override;
};
QJsonObject Person::toJson() const
{
QJsonObject json;
json["name"] = m_name;
json["age"] = m_age;
json["email"] = m_email;
json["address"] = m_address.toJson(); // 嵌套对象的JSON
return json;
}
Person Person::fromJson(const QJsonObject &json)
{
Person person;
// ... 解析name, age, email
if (json.contains("address") && json["address"].isObject()) {
person.m_address = Address::fromJson(json["address"].toObject());
}
return person;
}
2 数组/列表
如果类成员是一个QList、QVector等容器,我们需要使用QJsonArray。
Person有一个QStringList表示电话号码:
class Person
{
// ...
QStringList m_phoneNumbers;
// ...
QJsonObject toJson() const override;
static Person fromJson(const QJsonObject &json) override;
};
QJsonObject Person::toJson() const
{
QJsonObject json;
// ... 其他成员
QJsonArray phoneArray;
for (const QString &phone : m_phoneNumbers) {
phoneArray.append(phone);
}
json["phoneNumbers"] = phoneArray;
return json;
}
Person Person::fromJson(const QJsonObject &json)
{
Person person;
// ... 其他成员解析
if (json.contains("phoneNumbers") && json["phoneNumbers"].isArray()) {
QJsonArray phoneArray = json["phoneNumbers"].toArray();
for (const QJsonValue &value : phoneArray) {
if (value.isString()) {
person.m_phoneNumbers.append(value.toString());
}
}
}
return person;
}
使用Qt宏简化序列化/反序列化(可选)
对于非常复杂的类,



还没有评论,来说两句吧...