2016-09-26 6 views
2

Ich versuche herauszufinden, wie ich Aufzählungen in Qt verwenden soll, damit ich sie in einem QVariant packe und sie in einen QJsonValue und später JSON umwandeln.Qt, QVariant, JSON und enums

die docs Nach ich meine Aufzählungen endete erklärt:

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

So kann ich setValue(..) auf QVariant können meine benutzerdefinierte definiert Aufzählungen als Wert zu setzen. jedoch

Das Problem QJsonValue::fromVariant(), sagt der docs:

Wandelt Variante zu einem QJsonValue und gibt es zurück. (...) Für alle anderen QVariant-Typen wird eine Konvertierung in einen QString versucht. Wenn der zurückgegebene String leer ist, wird ein Null QJsonValue gespeichert, andernfalls ein String-Wert, der den zurückgegebenen QString verwendet.

Die Umstellung auf QString versagt und meine QJsonValue Objekt endet Null zu sein.

Nach der Dokumentation ist weiter verwirrend: Es gibt ein Q_EUM Makro für die Aufzählung Definition in QObject. Da QObject jedoch nicht kopierfähig ist, glaube ich nicht, dass QVariant es halten soll. Es gibt sicherlich einige Hackies, um es zum Laufen zu bringen, aber das ist nicht das, wonach ich suche. Was ist die empfohlene Vorgehensweise in Qt, Enums zu definieren, damit sie als Datentypen verwendet und in JSON konvertiert und von JSON gelesen werden können?

aktualisieren

versucht, die folgenden:

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

nun einen Typ ID und eine String-Darstellung hat es! Aber nicht die Klasse es hält:

int idRectangle = qMetaTypeId<Rectangle>(); 

lässt sich nicht kompilieren und ich kann es nicht mit Q_DECLARE_MEATYPE registrieren, weil es keinen Konstruktor hat. Was ist, wenn ich QVariants toString() brauche, um mit jeder Klasse zu arbeiten?

zweite Update

die Q_GADGET Makro jetzt eine (andere) Typ-ID für die ENUM und die Klasse es hält ich. Allerdings bekomme ich immer nur eine String-Repräsentation für die Enumeration.

Antwort

2

Q_ENUM oder Q_ENUMS werden benötigt, um die erforderliche Struktur QMetaEnum toString/fromString zu generieren.

Sie müssen in einer QObject abgeleiteten Klasse mit dem Q_OBJECT Marker oder in jeder Klasse mit dem Q_GADGET Marker um moc platziert werden, um sie zu verarbeiten und den erforderlichen Code zu generieren.

Die Klasse, in der sie definiert sind, wird jedoch nicht in der Variante gespeichert, wenn Sie einen Enum-Wert speichern. Sie können diese Klasse eher als einen "Namespace" für Ihre enum betrachten.

+0

Thx für die schnelle Antwort! – Nils

1

Ich dachte der Rest aus, um QVariant::toString() eine Konvertierung muss für den Typ von der QVariant registriert registriert werden.

Dies wurde von KDAB in Qt 5.2 (http://log.cedricbonhomme.org/55/66102.html) hinzugefügt, aber nirgends in der Dok. QVariant::toString() erwähnt! :(

Anyways funktioniert es auch für Normal Aufzählungen, das folgende Beispiel wird ausgegeben „Apple“

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

können Sie überprüfen, ob es einen Fehlerbericht gegen Dokumentation Qt darüber ist fehlend? –

+1

Musste eins erstellen: https://bugreports.qt.io/browse/QTBUG-56204 – Nils

+1

Ich würde vorschlagen, es stattdessen gegen Komponente "Dokumentation" zu melden. –