y.userType());
if (propValue.isValid()) {
property.write(result.data(), propValue);
}
}
}
return result;
}
private:
static QJsonValue variantToJsonValue(const QVariant& variant) {
if (variant.canConvert<QString>()) {
return QJsonValue::fromVariant(variant.toString());
}
else if (variant.canConvert<int>()) {
return QJsonValue::fromVariant(variant.toInt());
}
else if (variant.canConvert<double>()) {
return QJsonValue::fromVariant(variant.toDouble());
}
else if (variant.canConvert<bool>()) {
return QJsonValue::fromVariant(variant.toBool());
}
else if (variant.userType() == qMetaTypeId<QList<int>>()) {
return listToJsonArray<int>(variant.value<QList<int>>());
}
else if (variant.userType() == qMetaTypeId<QList<QString>>()) {
return listToJsonArray<QString>(variant.value<QList<QString>>());
}
else if (variant.userType() == qMetaTypeId<QList<bool>>()) {
return listToJsonArray<bool>(variant.value<QList<bool>>());
}
return QJsonValue::Null;
}
template<typename T>
static QJsonArray listToJsonArray(const QList<T>& list) {
QJsonArray jsonArray;
for (const T& value : list) {
jsonArray.append(QJsonValue::fromVariant(value));
}
return jsonArray;
}
static QVariant jsonValueToVariant(const QJsonValue& jsonValue, int userType) {
QVariant result;
if (jsonValue.isString()) {
result = jsonValue.toString();
}
else if (jsonValue.isDouble()) {
if (userType == QMetaType::Int) {
result = jsonValue.toInt();
}
else if (userType == QMetaType::Double) {
result = jsonValue.toDouble();
}
}
else if (jsonValue.isBool()) {
if (userType == QMetaType::Bool) {
result = jsonValue.toBool();
}
}
else if (jsonValue.isArray()) {
QJsonArray jsonArray = jsonValue.toArray();
if (userType == qMetaTypeId<QList<int>>()) {
QList<int> intList;
for (const QJsonValue& element : jsonArray) {
intList.append(element.toInt());
}
result = QVariant::fromValue(intList);
}
else if (userType == qMetaTypeId<QList<QString>>()) {
QList<QString> stringList;
for (const QJsonValue& element : jsonArray) {
stringList.append(element.toString());
}
result = QVariant::fromValue(stringList);
}
// Add more cases for other QList types if needed
}
return result;
}
};
#pragma endregion
当然了,Qt的元对象类型还有很多很强大的功能,比如对象名称等等,各种各样的功能,可以拿着Qt当C#来用了(笑)
但是
Qt的元对象类型也有很多局限性。正如我在前言中提到的,正因为Q_OBJECT宏的存在,QObject的对象是不能使用模板类继承的,也不能使用模板类多继承。这个实际上相当限制了Qt程序员的开发能力。模板类作为功能非常强大的一个功能,也正是C++能如此蓬勃发展的一个重要原因,结果在Qt上用不了,这是令人扼腕叹息的。
另外,值得一提的是,我们可以看到,在自己写继承的时候,从一个继承了QObject类和声明了Q_OBJECT宏的类中继承下来的子类仍然带有Q_OBJECT宏 这件事经常会通不过编译,我不知道自己是触犯了哪个规则,但是之后我的底层框架中最底层的部分都不会使用Q_OBJECT宏,直到我搞懂这件事,因为真的为了这个问题做了太多的妥协了。
二、关于Q_OBJECT等宏属性
如果要聊这个宏,我们得看一下这个宏做了什么,找到Qt Document:
Q_OBJECT宏必须出现在类定义的私有部分中,该类定义声明自己的信号和槽,或者使用Qt的元对象系统提供的其他服务。
#include <QObject>
class Counter : public QObject
{
Q_OBJECT
public:
Counter() { m_value = 0; }
int value