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

Posted

技术标签:

【中文标题】为 QVariant 指定非自定义类型转换器【英文标题】:Specify non-custom type converter for QVariant 【发布时间】:2020-04-28 04:50:53 【问题描述】:

我像这样使用 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());

但是 QVariant::toString() 方法在使用 float 属性时有一些不正确的行为:代码

float f = 0.0001;
qDebug() << QVariant(f).toString();
qDebug() << QVariant(f).value<QString>();

打印:

"9.999999747378752e-05"
"9.999999747378752e-05"

好的,我知道,有漂亮的 QString::number() 方法,

float f = 0.0001;
qDebug() << QString::number(f);

这给了我:

"0.0001"

但我不想让代码复杂化:

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);

不幸的是,Qt 给了我一个错误:

Error : static assertion failed: QMetaType::registerConverter: At least one of the types must be a custom type.

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

【问题讨论】:

【参考方案1】:

您正在尝试注册已注册的 floatQString 类型,因此出现错误:

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

查看documentation 中支持的类型列表。

一种解决方案是扩展 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;

输出:

Value: "0.0001"

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

QString stringified = attrValue.value<FQString>();

【讨论】:

以上是关于为 QVariant 指定非自定义类型转换器的主要内容,如果未能解决你的问题,请参考以下文章

自定义数据类型使用QVariant转换的方法

将函数返回从“std::vector<QString>”转换为“QVariant”

09.AutoMapper 之自定义类型转换器(Custom Type Converters)

qstring变量怎样转换为qvariant

qt中qvariant怎么转换成int

c++有混合类型吗