Qt 为QVariant指定非自定义类型转换器

Qt 为QVariant指定非自定义类型转换器,qt,qt5,Qt,Qt5,我使用QObject属性序列化,如下所示: QMetaProperty metaProperty = obj->metaObject()->property(i); QString attrName = metaProperty.name(); QVariant attrValue = metaProperty.read(obj); serializedJson.insert("name", attrName); serializedJson.insert("value", attr

我使用QObject属性序列化,如下所示:

QMetaProperty metaProperty = obj->metaObject()->property(i);
QString attrName = metaProperty.name();
QVariant attrValue = metaProperty.read(obj);
serializedJson.insert("name", attrName);
serializedJson.insert("value", attrValue.toString());
但是当使用
float
properties:code时,QVariant::toString()方法有一些不正确的行为

float f = 0.0001;
qDebug() << QVariant(f).toString();
qDebug() << QVariant(f).value<QString>();
好的,我知道,有一个非常好的QString::number()方法

但我不想让代码复杂化:

QMetaProperty metaProperty = obj->metaObject()->property(i);
QString attrName = metaProperty.name();
QVariant attrValue = metaProperty.read(obj);

QString stringified = "";

// special handling of float properties !
if (attrValue.type() == static_cast<QVariant::Type>(QMetaType::Float))
    stringified = QString::number(attrValue.toFloat());
else
    stringified = attrValue.value<QString>();

serializedJson.insert("name", attrName);
serializedJson.insert("value", stringified );

如何为人类可读的类型序列化定义自定义类型转换?

您试图注册已注册的
float
QString
类型,因此出现错误:

静态断言失败:
QMetaType::registerConverter
:至少一个类型必须是自定义类型

请参阅中支持的类型列表

一种解决方案是扩展
QString
以创建自定义类型

下面是一个例子:

#include <QDebug>
#include <QString>
#include <QVariant>
#include <QMetaType>

struct FQString final : QString
{
    using QString::operator=;

    static QString convert( const float f )
    {
        return QString::number( f );
    }
};

Q_DECLARE_METATYPE( FQString );

int main()
{
    QMetaType::registerConverter<float, FQString>( FQString::convert );

    const float f = 0.0001;
    const QVariant v( f );

    const QString s = v.value<FQString>();
    qDebug() << "Value:" << s;

    return 0;
}
使用此解决方案,您可以为代码编写如下内容:

QString stringified = attrValue.value<FQString>();
QString stringified=attrValue.value();
QMetaProperty metaProperty = obj->metaObject()->property(i);
QString attrName = metaProperty.name();
QVariant attrValue = metaProperty.read(obj);

QString stringified = "";

// special handling of float properties !
if (attrValue.type() == static_cast<QVariant::Type>(QMetaType::Float))
    stringified = QString::number(attrValue.toFloat());
else
    stringified = attrValue.value<QString>();

serializedJson.insert("name", attrName);
serializedJson.insert("value", stringified );
QMetaType::registerConverter<float, QString>(Converters::floatToString);
Error : static assertion failed: QMetaType::registerConverter: At least one of the types must be a custom type.
#include <QDebug>
#include <QString>
#include <QVariant>
#include <QMetaType>

struct FQString final : QString
{
    using QString::operator=;

    static QString convert( const float f )
    {
        return QString::number( f );
    }
};

Q_DECLARE_METATYPE( FQString );

int main()
{
    QMetaType::registerConverter<float, FQString>( FQString::convert );

    const float f = 0.0001;
    const QVariant v( f );

    const QString s = v.value<FQString>();
    qDebug() << "Value:" << s;

    return 0;
}
Value: "0.0001"
QString stringified = attrValue.value<FQString>();