首页 前端知识 【无标题】QT json 序列化反序列化

【无标题】QT json 序列化反序列化

2024-08-10 22:08:00 前端知识 前端哥 856 931 我要收藏
/*****************************************************************
 *  @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()

*/

转载请注明出处或者链接地址:https://www.qianduange.cn//article/15304.html
标签
pyqt
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!