2016-09-26 69 views
2

我想弄清楚我應該如何在Qt中使用枚舉,以便將它們打包到QVariant中並將它們轉換爲QJsonValue和後來的JSON。Qt,QVariant,JSON和枚舉

繼我結束了我的聲明枚舉文檔:

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

這樣,我可以使用QVariantsetValue(..)設置我的自定義的枚舉作爲價值。

的問題但是是QJsonValue::fromVariant(),該文檔稱:

轉換變到QJsonValue並將其返回。 (...) 對於所有其他QVariant類型,嘗試轉換爲QString將會嘗試 。如果返回的字符串爲空,則存儲空值QJsonValue ,否則使用返回的QString的字符串值。

轉換爲QString失敗,而我的QJsonValue對象最終爲空。

以下文檔進一步令人困惑:在QObject中有一個用於枚舉定義的Q_EUM宏。但是因爲QObject是不可複製的,我不認爲QVariant應該保持它。確實有一些黑客想讓它工作,但那不是我正在尋找的。在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

Q_ENUMQ_ENUMS需要生成必要的QMetaEnum結構toString/fromString功能。

他們需要,以便被放置在一個QObject派生類與Q_OBJECT標記或與該標記Q_GADGET任何類moc處理它們,併產生必要的代碼。

雖然存儲枚舉值時,它們定義的類並不是存儲在變體中的類。 你可以認爲這個類更像是你的枚舉的「命名空間」。

+0

THX的快速答覆! – Nils

1

我想出了其他的,爲了能夠使用QVariant::toString()轉換必須註冊爲由QVariant所持有的類型。

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

反正它也適用於普通的枚舉,下面的例子將輸出「蘋果」

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

你能檢查是否有針對文檔在Qt的這個bug報告丟失了嗎? –

+1

必須創建一個:https://bugreports.qt.io/browse/QTBUG-56204 – Nils

+1

我建議用組件「文檔」報告它。 –