最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

微动态丨【QtJson】用Qt自带的QJson,直接一步到位封装和解析一个类的实例对象!

来源:博客园


【资料图】

之前貌似没有看过类似的代码我们现在的要求就是直接在不知道类成员的情况下,把一个类丢进去就能生成一个Json字符串,也可以把一个字符串和一个类成员丢进去就能根据成员变量名匹配到元素并赋值,大概就这样

中心思想就是Q_PROPERTY宏提供了一个property类型,可以直接通过变量名称获得一个变量名称对应的字符串,比如int a;可以直接获得一个"a"的字符串,而且还可以知道这个a 的类型。并据此来进行字符串的封装和解析。

主要是为了开发方便,就可以直接把一个QObject对象扔进去返回一个字符串,也可以把一个Json字符串和指定类的对象扔进去就直接自动把类中对应的属性修改了,总的来说应该是用点用。

#pragma region Example调用实例//Json相关方法调用实例://// 如果想要调用JsonMaker类来把你的类成员元素,假设是A a,其中包含元素qint32 a1,QString a2,bool a3进行封装,那么你需要使用Q_PROPERTY来// 声明封装a1,a2,a3元素和其set/get方法(如果需要解析就需要set方法,如果需要封装就需要get方法),set/get方法命名规则为set/get+元素名称// 比如seta1,geta2,其中不对大小写做规定,也可以写成setA1,getA2// // 调用方法如下:// 1.封装字符串// A a; // QString result = JsonMaker::Singleton().JsonSerialization(tester);// 2.解析字符串// A a// JsonMaker::Singleton().JsonDeserialization(a, Json);// 调用完毕后a中的对应数据都会被Json字符串中的数据覆盖////测试解析、封装类举例:class Tester1 :public QObject {Q_OBJECTQ_PROPERTY(QString name READ getName WRITE setname)Q_PROPERTY(QString like READ getLike WRITE setlike)Q_PROPERTY(QString birthday READ getBirthday WRITE setbirthday)//Q_PROPERTY(QString str_public READ str_public,WRITE setStr_public)Q_PROPERTY(QList list READ getList WRITE setlist)Q_PROPERTY(QList qint32_list READ getqint32_List WRITE setqint32_list)//暂时不支持float类型//Q_PROPERTY(QList float_list READ getFloat_List)Q_PROPERTY(QList double_list READ getDouble_List WRITE setdouble_list)Q_PROPERTY(QList bln_list READ getBln_List WRITE setbln_list)Q_PROPERTY(QList int_list READ getInt_list WRITE setint_list)public:Tester1(QObject* parent = Q_NULLPTR);//QString str_public = "str_public";#pragma region get funcsQString getName() {return name;}QString getLike() {return like;}QString getBirthday() {return birthday;}QList getList() {return this->list;}QList getInt_list() {return this->int_list;}QList getqint32_List() {return this->qint32_list;}QList getFlost_List() {return this->float_list;}QList getDouble_List() {return this->double_list;}QList getBln_List(){return this->bln_list;}QList getFloat_List() {return float_list;}#pragma endregion#pragma region Set Funcs/*QList list = { "123","234","345","4356" };QList qint_list = { 123,234,345,456 };QList float_list = { 1.123123,2.234234,4.345345,45.457457 };QList double_list = { 1.2443,3.52,2.351,1.235 };QList int_list = { 234,345,456,567,678,123,32 };QList bln_list = { true,false,true,false };*/Q_INVOKABLE void setlist(QList list_value) {this->list = list_value;}Q_INVOKABLE void setqint32_list(QList list_value) {this->qint32_list = list_value;}Q_INVOKABLE void setdouble_list(QList list_value) {this->double_list = list_value;}Q_INVOKABLE void setint_list(QList list_value) {this->int_list = list_value;}Q_INVOKABLE void setbln_list(QList list_value) {this->bln_list = list_value;}Q_INVOKABLE void setname(QString strValue) {this->name = strValue;}Q_INVOKABLE void setlike(QString strValue) {this->like = strValue;}Q_INVOKABLE void setbirthday(QString strValue) {this->birthday = strValue;}#pragma endregionprivate:QString name = "name";QString like = "like";QString birthday = "birthday";QList list = { "123","234","345","4356" };QList qint32_list = { 123,234,345,456 };QList float_list = { 1.123123,2.234234,4.345345,45.457457 };QList double_list = { 1.2443,3.52,2.351,1.235 };QList int_list = { 234,345,456,567,678,123,32 };QList bln_list = { true,false,true,false };};#pragma endregion//Json相关//给定任意模板类,将其公开属性打包成一个Json字符串,使用此方法需要所有的公开属性均为Q_PROPERTY宏声明,该类提供单例。//序列化类Q_PROPERTY宏声明的属性 set/get函数命名规则:get/set+属性名 如getBirthday setList,大小写不限,如果是set方法需要在set方法前面加上Q_INVOKABLE 宏//如果需要反序列化数组,请保证数组中的所有数据结构是同一个类型,否则可能会出错//注:请尽量使用int不要使用qint32,使用double不要使用floatclass JsonMaker :public QObject {JsonMaker();//提供单例public:static JsonMaker& JsonMaker::Singleton() {static JsonMaker Instance;return Instance;// TODO: 在此处插入 return 语句}//序列化类Q_PROPERTY宏声明的属性,如果有数组类型,请使用QListtemplateQString JsonSerialization(T1& T_Class_1) {auto T_Class = dynamic_cast(&T_Class_1);QJsonObject jsonObject;//通过元对象定义成员const QMetaObject* metaObject = T_Class->metaObject();for (int i = 0; i < metaObject->propertyCount(); ++i) {QMetaProperty property = metaObject->property(i);if (!property.isReadable()) {continue;}//这个不知道是什么,暂时需要先屏蔽掉if (QString(property.name()) == "objectName") {continue;}//如果是QListif (QString(property.typeName()).contains("QList")) {//这里可能要根据常见类型进行一下分类QJsonArray jsonListArray;//输入一个模板类类型,输出一个jsonObjectif (QString(property.typeName()) == "QList") {QList str_message = property.read(T_Class).value>();jsonListArray = QListToJsonArray(str_message);}else if (QString(property.typeName()) == "QList" || QString(property.typeName()) == "QList") {QList str_message = property.read(T_Class).value>();jsonListArray = QListToJsonArray(str_message);}else if (QString(property.typeName()) == "QList") {QList str_message = property.read(T_Class).value>();jsonListArray = QListToJsonArray(str_message);}else if (QString(property.typeName()) == "QList") {QList str_message = property.read(T_Class).value>();jsonListArray = QListToJsonArray(str_message);}else if(QString(property.typeName()) == "QList") {QList str_message = property.read(T_Class).value>();jsonListArray = QListToJsonArray(str_message);}else if (QString(property.typeName()) == "QList") {QList str_message = property.read(T_Class).value>();jsonListArray = QListToJsonArray(str_message);}else if (QString(property.typeName()) == "QList") {QList str_message = property.read(T_Class).value>();jsonListArray = QListToJsonArray(str_message);}else if (QString(property.typeName()) == "QList") {QList str_message = property.read(T_Class).value>();jsonListArray = QListToJsonArray(str_message);}jsonObject.insert(property.name(), QJsonValue(jsonListArray));}//如果不是QListelse {QVariant result = property.read(T_Class);jsonObject[property.name()] = QJsonValue::fromVariant(property.read(T_Class));}qDebug() << property.name();}QJsonDocument doc(jsonObject);return doc.toJson(QJsonDocument::Compact);}//反序列化类Q_PROPERTY宏声明的属性,如果有数组类型,请使用QListtemplatevoid JsonDeserialization(T& T_Class, const QString& jsonString){auto qobject = dynamic_cast(&T_Class);QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8());QJsonObject jsonObject = doc.object();// 使用QMetaObject的invokeMethod()函数来调用模板类T的setter函数const QMetaObject* metaObject = qobject->metaObject();for (int i = 0; i < metaObject->propertyCount(); ++i) {QMetaProperty property = metaObject->property(i);if (property.isReadable() && property.isWritable()) {QString propertyName = property.name();QString str_functinoname = QString("set" + propertyName);//为了转换成const char*类型必须的一个中间步骤QByteArray temp_qba_functinoname = str_functinoname.toLocal8Bit();const char* func_name = temp_qba_functinoname.data();if (jsonObject.contains(propertyName)) {QJsonValue value = jsonObject[propertyName];JsonMaker temp;qDebug() << value;switch (value.type()) {case QJsonValue::Type::Bool:QMetaObject::invokeMethod(qobject, func_name, Q_ARG(bool, value.toBool()));break;case QJsonValue::Type::Double:QMetaObject::invokeMethod(qobject, func_name, Q_ARG(double, value.toDouble()));break;case QJsonValue::Type::String:QMetaObject::invokeMethod(qobject, func_name, Q_ARG(QString, value.toString()));break;case QJsonValue::Type::Array: {//如果是数组则需要根据情况进行解析if (!value.isArray()) {break;}QJsonArray arr = value.toArray();//下面确定数组类型this->JsonArrayDeserialization(qobject, func_name, arr);}break;case QJsonValue::Type::Object:QMetaObject::invokeMethod(qobject, func_name, Q_ARG(QJsonValue, value));break;default:break;}}}}}private://将模板类QList转换成JsonObjecttemplateQJsonArray QListToJsonArray(QList list) {QJsonArray jsonArray;for each (T temp_T in list){jsonArray.append(QJsonValue::fromVariant(temp_T));}return jsonArray;}//解析数组并注入QObject对象void JsonArrayDeserialization(QObject* qobject, const char* func_name, QJsonArray arr) {try { //判断类型//QStringif (arr[0].type() == QJsonValue::String) {QList list_result;QJsonValue value;for each (QJsonValue temp_value in arr){list_result.append(temp_value.toString());}QMetaObject::invokeMethod(qobject, func_name, Q_ARG(QList, list_result));}else if (arr[0].isDouble()) {//若为为整形if (arr[0].toDouble() == arr[0].toInt()) {qDebug() << arr[0].toDouble() << arr[0].toInt();QList list_result;QList list_result_2;QJsonValue value;for each (QJsonValue temp_value in arr){//int 和 qint32都需要尝试,但请尽量尝试使用qint32,这段代码占用了两倍的内存,将来可能考虑删除list_result.append(temp_value.toInt());list_result_2.append(temp_value.toInt());}if (!QMetaObject::invokeMethod(qobject, func_name, Q_ARG(QList, list_result))) {QMetaObject::invokeMethod(qobject, func_name, Q_ARG(QList, list_result_2));}}//若为双精度else {QList list_result;QList list_result_2;QJsonValue value;for each (QJsonValue temp_value in arr){list_result.append(temp_value.toDouble());}//double和float都会尝试,请尽量使用doubleif (!QMetaObject::invokeMethod(qobject, func_name, Q_ARG(QList, list_result))) {QMetaObject::invokeMethod(qobject, func_name, Q_ARG(QList, list_result_2));}}}if (arr[0].type() == QJsonValue::Bool) {QList list_result;QJsonValue value;for each (QJsonValue temp_value in arr){list_result.append(temp_value.toBool());}QMetaObject::invokeMethod(qobject, func_name, Q_ARG(QList, list_result));}}catch (const QException& e) {WriteErrorMessage("JsonArrayDeserialization","JsonArrayDeserialization", e.what());}}};}#endif // LBD_BASETOOLS

关键词: 数组类型 反序列化 数据结构