Qt,QVariant,JSON和枚举

时间:2016-09-26 15:42:59

标签: c++ json qt enums

我试图弄清楚我应该如何在Qt中使用枚举,以便将它们打包在QVariant中并将它们转换为QJsonValue以及后来的JSON。

根据文档,我最终宣布了我的枚举:

enum BeautifulColors { Red, Green, Blue };
Q_DECLARE_METATYPE(BeautifulColors);

这样我就可以setValue(..)使用QVariant将我自定义的枚举设置为值。

问题是QJsonValue::fromVariant(),文档说:

  

将变体转换为QJsonValue并返回它。 (......)   对于所有其他QVariant类型,将转换为QString   尝试。如果返回的字符串为空,则为空QJsonValue   存储,否则使用返回的QString的String值。

转换为QString失败,而我的QJsonValue对象最终为空。

在文档之后进一步令人困惑:QObject中的枚举定义有一个Q_EUM宏。但是,由于QObject是不可复制的,我不认为QVariant应该持有它。肯定有一些hacky是让它工作,但这不是我想要的。 Qt中定义枚举的推荐方法是什么,以便它们可以用作数据类型并转换为JSON并从JSON读取?

更新

尝试以下方法:

rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H

#include <QObject>

class Rectangle : public QObject
{
    Q_OBJECT

public:

    enum Color
    {
        Red,
        Green,
        Blue,
    };

    Q_ENUM(Color)

    Rectangle(double x, double y, Color color, QObject *parent = 0);

private:

    double _x;
    double _y;
    Color _color;
};

#endif

rectangle.cpp
#include "rectangle.h"

Rectangle::Rectangle(double x, double y, Rectangle::Color color, QObject *parent)
    : QObject(parent)
    , _x(x)
    , _y(y)
    , _color(color)
{

}

main.cpp
#include <QVariant>
#include <QDebug>
#include <QString>

#include "rectangle.h"
int main(int argc, char *argv[])
{
    int id = qMetaTypeId<Rectangle::Color>();
    Rectangle::Color blueColor = Rectangle::Blue;
    QVariant myVariant;
    myVariant.setValue(blueColor);
    qDebug() << id;
    qDebug() << myVariant.toString();
}

现在它有一个典型ID和一个字符串表示!但不是持有它的班级:

int idRectangle = qMetaTypeId<Rectangle>();

不编译,我无法在Q_DECLARE_MEATYPE注册,因为它没有构造函数。如果我需要QVariants toString()来处理任何类,该怎么办?

第二次更新

使用Q_GADGET宏我现在为枚举和持有它的类获得(不同的)类型id。但是我仍然只获得枚举的字符串表示。

2 个答案:

答案 0 :(得分:3)

Q_ENUMQ_ENUMS需要为toString / fromString功能生成必要的QMetaEnum结构。

他们需要使用QObject标记放置在Q_OBJECT派生类中,或者放在带有Q_GADGET标记的任何类中,以便moc处理它们并生成必要的代码。

虽然存储枚举值时,它们所定义的类不是存储在变体中的类。 你可以认为这个类更像是一个&#34;命名空间&#34;为你的枚举。

答案 1 :(得分:1)

我认为剩下的就是,为了能够使用QVariant::toString(),必须为QVariant持有的类型注册转换。

这是由KDAB在Qt 5.2(http://log.cedricbonhomme.org/55/66102.html)中添加的,但在文档QVariant::toString()中没有提及! :(

无论如何它也适用于普通枚举,以下示例将输出&#34; Apple&#34;

enum Fruit {
    Apple,
    Pear,
    Orange
};

Q_DECLARE_METATYPE(Fruit)

QString Fruit2QString(Fruit fruit)
{
    switch(fruit)
    {
        case Apple:
            return "Apple";
        case Pear:
            return "Pear";
        case Orange:
            return "Orange";
    }

    return "asdf";
}

int main(int argc, char *argv[])
{
    std::function<QString(Fruit)> f = &Fruit2QString;
    bool success = QMetaType::registerConverter<Fruit, QString>(f);
    Q_ASSERT(success);
    QVariant v;
    v.setValue(Fruit::Apple);
    qDebug() << v.toString();
}