Укажите нестандартный конвертер типов для QVariant - PullRequest
0 голосов
/ 28 апреля 2020

Я использую сериализацию свойства 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 Ответ

0 голосов
/ 28 апреля 2020

Вы пытаетесь зарегистрировать float и QString типы, которые уже зарегистрированы, поэтому возникает ошибка:

stati c утверждение не выполнено: 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;
}

Вывод:

Value: "0.0001"

С этим решением вы можете написать что-то вроде этого для своего кода:

QString stringified = attrValue.value<FQString>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...