2016-09-26 10 views
2

Qtで列挙型を使用してQVariantにパックし、QJsonValueとそれ以降のJSONに変換する方法を理解しようとしています。私は私の列挙型を宣言することになったドキュメントに続きQt、QVariant、JSON、enums

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

私は値として私のカスタム定義された列挙型を設定するQVariantsetValue(..)を使用することができますこの方法。

問題はしかしQJsonValue::fromVariant()で、ドキュメントは言う:

はQJsonValueにバリアントを変換し、それを返します。 (...) 他のすべてのQVariantタイプでは、QStringへの変換は、 が試みられます。返される文字列が空の場合、Null QJsonValueは に格納され、そうでない場合は返されたQStringを使用してString値が格納されます。

QStringへの変換が失敗し、QJsonValueオブジェクトがNullになってしまいます。

ドキュメントの後に、さらに混乱が生じます。QObject内に列挙型定義用のQ_EUMマクロがあります。しかし、QObjectはコピーできないので、私はQVariantがそれを保持しているとは思わない。確かにいくつかのハッキーがそれを働かせることがありましたが、それは私が探しているものではありません。列挙型をデータ型として使用し、JSONに変換してJSONから読み込むことができるように、Qtで推奨される方法は何ですか?

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()を使用してクラスを操作する必要がある場合はどうすればよいですか?

私は今、(異なる)を取得列挙し、それを保持するクラスのIDを入力Q_GADGETマクロを使用して、第2の更新

。しかし、私はまだenumの文字列表現しか得ていません。

答えて

2

Q_ENUMまたはQ_ENUMSは、toString/fromString機能に必要なQMetaEnum構造体を生成するために必要です。

彼らはそれらを処理し、必要なコードを生成するmocためにQ_OBJECTマーカーまたはQ_GADGETマーカーと任意のクラスでQObject派生クラスに配置する必要があります。

定義されているクラスは、列挙型の値を格納するときにバリアントに格納されるクラスではありません。 このクラスは、enumの「名前空間」のようなものです。

+0

Thxを! – Nils

1

QVariant::toString() QVariantが保持するタイプの変換を登録する必要があります。

これはQt 5.2(http://log.cedricbonhomme.org/55/66102.html)でKDABによって追加されましたが、doc QVariant::toString()でもここに記載されていません! :(

はとにかくそれはまた、このことについてはQtのドキュメントに対するバグ報告がある場合、次の例の出力は「アップル」迅速な回答を

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(); 
} 
+0

あなたがチェックすることができます、平野列挙型のために働きます –

+1

作成する必要がありました:https://bugreports.qt.io/browse/QTBUG-56204 – Nils

+1

代わりにコンポーネント "ドキュメント"に対して報告することをお勧めします。 –