/*****************************************************************
* @project :IntelligentAnalysisGyk15
* @File : JsonSerialize.h
* @Author : zym1
* @Date : 2024-03-06 17:12
* @Version : v1.0
* @Copyright : Copyright By Zhuy, All Rights Reserved
******************************************************************/
#ifndef JSONSERIALIZE_H
#define JSONSERIALIZE_H
// json 序列化
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QVariant>
#include <QVariantList>
#include <QVariantMap>
///@brief 序列化. object to Json, object to Variant or VariantMap
#define JsonSerialize_Begin() \
public: \
operator QVariant() const \
{ \
return QVariant::fromValue(this->operator QVariantMap()); \
} \
operator QJsonObject() const \
{ \
return QJsonObject::fromVariantMap(this->operator QVariantMap()); \
} \
operator QVariantMap() const \
{ \
QVariantMap vmap;
#define JsonSerialize_End() \
return vmap; \
}
///@brief 序列化属性映射
#define JsonPureProperty(NAME) vmap.unite((QVariantMap)m_##NAME);
#define JsonProperty(NAME) \
vmap[#NAME] = QVariant::fromValue(m_##NAME); \
if (vmap.value(#NAME).isNull()) \
vmap.remove(#NAME);
#define JsonContainerProperty(NAME) \
{ \
QVariantList lst; \
lst.reserve(m_##NAME.size()); \
for (const auto& t : m_##NAME) \
{ \
lst << QVariant::fromValue(t); \
} \
vmap[#NAME] = lst; \
}
///@brief 反序列化 object from json
#define JsonDeserialize_Begin(class_name) \
public: \
class_name(const QJsonObject& other) \
{ \
QVariantMap vmap = other.toVariantMap();
#define JsonDeserialize_End() }
///@brief 部分反序列化
#define JsonPartialDeserialize_Begin(class_name) \
public: \
class_name& operator=(const QJsonObject& other) \
{ \
QVariantMap vmap = other.toVariantMap();
#define JsonPartialDeserialize_End() \
return *this; \
}
#define JsonDeserializeContainerProperty(NAME) \
if (vmap.value(#NAME).canConvert<QVariantList>()) \
{ \
const auto& list = vmap.value(#NAME).value<QVariantList>(); \
m_##NAME.clear(); \
m_##NAME.reserve(list.size()); \
for (const auto& v : list) \
{ \
m_##NAME.push_back(v.value<decltype(m_##NAME)::value_type>()); \
} \
}
#define JsonDeserializeProperty(NAME) m_##NAME = vmap.value(#NAME).value<decltype(m_##NAME)>();
#endif // JSONSERIALIZE_H
/*****************************************************************
* @project :IntelligentAnalysisGyk15
* @File : PropertyHelper.h
* @Author : zym
* @Date : 2024-03-06 17:12
* @Version : v1.0
* @Copyright : Copyright By Zhuy, All Rights Reserved
******************************************************************/
#ifndef PROPERTYHELPER_H
#define PROPERTYHELPER_H
#include <QObject>
#include <QtGlobal>
// 比较器的 声明
template <typename T>
struct Compare;
// 通用比较器
template <typename T>
struct Compare
{
static bool isEqual(const T& t1, const T& t2)
{
return t1 == t2;
}
};
//**********************************普通成员及函数**********************************
// 成员变量
#define PROP_MEM(T, NAME, InitValue) T m_##NAME = InitValue;
// 普通 get 函数
#define MEM_GET(T, NAME) \
const T& NAME() const \
{ \
return m_##NAME; \
}
// 普通 set 函数
#define MEM_SET(T, NAME) \
void set_##NAME(const T& value) \
{ \
m_##NAME = value; \
}
// 普通 可读可写 成员及函数
#define AUTO_MEM(T, NAME, InitValue) \
public: \
MEM_GET(T, NAME) \
MEM_SET(T, NAME) \
private: \
PROP_MEM(T, NAME, InitValue)
//**********************************QObject 属性**********************************
// 属性 change 信号
#define PROP_CHANGE(T, NAME) Q_SIGNAL void NAME##Changed(const T& value);
// 属性 get 函数 (和普通get没区别)
#define PROP_GET(T, NAME) MEM_GET(T, NAME)
// 属性 set 函数 (比普通set 多 changeCheck,change 时发信号. check 时处理 float 和 double 数据的精度)
#define PROP_SET(T, NAME) \
void set_##NAME(const T& value) \
{ \
if (Compare<T>::isEqual(m_##NAME, value)) \
return; \
m_##NAME = value; \
emit NAME##Changed(value); \
}
// 只读属性,外部不能改
#define READONLY_PROPERTY(T, NAME, InitValue) \
private: \
Q_PROPERTY(T NAME READ NAME CONSTANT) \
public: \
PROP_GET(T, NAME) \
private: \
PROP_MEM(T, NAME, InitValue)
// 可读属性,比只读属性 多一个 属性set函数。
#define READ_PROPERTY(T, NAME, InitValue) \
private: \
Q_PROPERTY(T NAME READ NAME NOTIFY NAME##Changed) \
public: \
PROP_GET(T, NAME) \
PROP_SET(T, NAME) \
PROP_CHANGE(T, NAME) \
private: \
PROP_MEM(T, NAME, InitValue)
// 可读可写 属性。属性set函数 提升为 slot ,可被 invok / qml 调用
#define AUTO_PROPERTY(T, NAME, InitValue) \
private: \
Q_PROPERTY(T NAME READ NAME WRITE set_##NAME NOTIFY NAME##Changed) \
public: \
PROP_GET(T, NAME); \
Q_SLOT PROP_SET(T, NAME); \
PROP_CHANGE(T, NAME); \
\
private: \
PROP_MEM(T, NAME, InitValue)
//**********************************QObject 属性 二进制兼容版, 头文件声明 与 源文件定义 分离**********************************
// 属性 get 函数声明
#define PROP_GET_DECL(T, NAME) const T& NAME() const;
// 属性 set 函数声明
#define PROP_SET_DECL(T, NAME) void set_##NAME(const T& value);
// d 指针类型名
#define D_TYPE PrivateData
// d 指针成员变量名
#define D_NAME dPtr
// d 指针的声明
#define D_DECL \
private: \
struct D_TYPE; \
D_TYPE* D_NAME = nullptr;
// d 指针的定义
#define D_IMPL(ClassName) struct ClassName::D_TYPE
// d 类的成员
#define D_MEM(T, NAME, InitValue) PROP_MEM(T, NAME, InitValue)
// 属性 get 函数定义
#define PROP_GET_IMPL(ClasName, T, NAME) \
const T& ClasName::NAME() const \
{ \
return D_NAME->m_##NAME; \
}
// 属性 set 函数定义
#define PROP_SET_IMPL(ClasName, T, NAME) \
void ClasName::set_##NAME(const T& value) \
{ \
if (Compare<T>::isEqual(D_NAME->m_##NAME, value)) \
return; \
D_NAME->m_##NAME = value; \
emit NAME##Changed(value); \
}
// 可读可写 属性声明。
#define AUTO_PROPERTY_DECL(T, NAME) \
private: \
Q_PROPERTY(T NAME READ NAME WRITE set_##NAME NOTIFY NAME##Changed) \
public: \
PROP_GET_DECL(T, NAME); \
public slots: \
PROP_SET_DECL(T, NAME); \
signals: \
PROP_CHANGE(T, NAME)
// 可读可写 属性定义。
#define AUTO_PROPERTY_IMPL(ClassName, T, NAME) \
PROP_GET_IMPL(ClassName, T, NAME) \
PROP_SET_IMPL(ClassName, T, NAME)
#endif // PROPERTYHELPER_H
/**
- Example:
class AppInfo : public QObject
{
Q_OBJECT
AUTO_PROPERTY(QString, appName, "")
AUTO_PROPERTY(bool, splashShow, false)
AUTO_PROPERTY(float, scale, 1.0f)
AUTO_PROPERTY(double, ratio, 14.0 / 9.0)
AUTO_PROPERTY(QStringList, customs, {})
JsonSerialize_Begin()
JsonProperty(appName)
JsonProperty(splashShow)
JsonProperty(scale)
JsonProperty(ratio)
JsonContainerProperty(customs)
JsonSerialize_End()
JsonDeserialize_Begin(AppInfo)
JsonDeserializeProperty(appName)
JsonDeserializeProperty(splashShow)
JsonDeserializeProperty(scale)
JsonDeserializeProperty(ratio)
JsonDeserializeContainerProperty(customs)
JsonDeserialize_End()
JsonPartialDeserialize_Begin(AppInfo)
JsonDeserializeProperty(appName)
JsonDeserializeProperty(splashShow)
JsonDeserializeProperty(scale)
JsonDeserializeProperty(ratio)
JsonDeserializeContainerProperty(customs)
JsonPartialDeserialize_End()
public:
explicit AppInfo(QObject *parent = nullptr);
virtual ~AppInfo() override;
};
these MACOR will generate these function:
AppInfo(const QJsonobject &obj)
AppInfo &operator=(const QJsonobject &obj)
operator QJsonobject()
operator QVariantMap()
operator QVariant()
*/