2015-12-15 12 views
22

Próbuję użyć odbicie Qt do konwersji enum na QString.Jak przekonwertować enum na QString?

Oto część kodu:

class ModelApple 
{ 
    Q_GADGET 
    Q_ENUMS(AppleType) 
public: 
    enum AppleType { 
     Big, 
     Small 
    } 
} 

I tu jest i próbuje zrobić:

convertEnumToQString(ModelApple::Big) 

Return "Big"

to jest możliwe? Jeśli masz jakiś pomysł na temat convertEnumToQString, podziel go

Odpowiedz

31

Musisz użyć makro Q_ENUM, h rejestruje typ wyliczeniowy w systemie metaobiektowym.

enum AppleType { 
    Big, 
    Small 
}; 
Q_ENUM(AppleType) 

I teraz można użyć klasy QMetaEnum dostęp do meta-dane o wyliczający.

QMetaEnum metaEnum = QMetaEnum::fromType<ModelApple::AppleType>(); 
qDebug() << metaEnum.valueToKey(ModelApple::Big); 

Oto ogólny szablon dla takiego narzędzia:

template<typename QEnum> 
std::string QtEnumToString (const QEnum value) 
{ 
    return std::string(QMetaEnum::fromType<QEnum>().valueToKey(value)); 
} 
+5

'QMetaEnum :: fromType ' jest dostępne od Qt 5, nie istnieje w Qt 4. Powinieneś dodać tę uwagę. Nawiasem mówiąc, nie polecam używać 'QMetaEnum :: key', ponieważ bierze on' index' jako parametr, jak to się stało, że zadeklarował 'enum AppleType {Big = 2, Small}' – Danh

+3

Z dokumentów wygląda to tak: jest to w rzeczywistości dostępne tylko z Qt 5.5, więc nadal potrzebuję użyć mojej metody w odpowiedzi, którą dałem (miał zamiar zaktualizować mój kod, ale na razie muszę używać Qt 5.4). –

8

Poniższy powinno Ci będzie:

QString convertEnumToQString(ModelApple::AppleType type) { 
    const QMetaObject metaObject = ModelApple::staticMetaObject; 
    int enumIndex = metaObject.indexOfEnumerator("AppleType"); 
    if(enumIndex == -1) { 
     /* The enum does not contain the specified enum */ 
     return ""; 
    } 
    QMetaEnum en = metaObject.enumerator(enumIndex); 
    return QString(en.valueToKey(type)); 
} 
+0

Dlaczego nie dołączyć do oświadczenia 'enumString' i' enumString = en.valueToKey (type); 'wywoła tylko 1 konstruktor zamiast 1 konstruktora i 1' operator = '. Możemy również wyeliminować sprawdzanie z '-1', ponieważ jesteśmy pewni, że to wyliczenie istnieje. – Danh

+0

Więc muszę określić moduł wyliczający "AppleType"? – Jiu

+0

@Danh Tak, możesz to zrobić. Mój aktualny kod to funkcja szablonu, która przyjmuje nazwę wyliczenia i wartość wyliczenia, aby zwrócić ciąg znaków. Zmodyfikowałem go, aby odpowiedzieć na pytanie. Moje użycie to 'string = convertEnumToQString (" AppleType ", ModelApple :: Big);' tak muszę sprawdzić poprawne wyliczenie i potwierdzić, jeśli nie jest prawidłowe do debugowania. Również twierdzę przed powrotem, a więc powód pierwszego przypisania, a następnie powrotu (wyłącznie do debugowania). –

2

Jak o:

QString convertEnumToQString(ModelApple::AppleType type) 
{ 
    const QMetaObject &mo = ModelApple::staticMetaObject; 
    int index = mo.indexOfEnumerator("AppleType"); 
    QMetaEnum metaEnum = mo.enumerator(index); 
    return metaEnum.valueToKey(type); 
} 

AKTUALIZACJA: Qt 5.5, patrz this answer

+0

Edytowany Qt 5 -> Qt 5.5, dzięki. – Danh

1

I w obliczu tego samego problemu i to jest jak rozwiązać go. Jest to szczególnie dla Qt 4,8

QString string = enumToString(ModelApple::Big); 

QString ModelApple::enumToString(AppleType apple) 
{ 
    int index = metaObject()->indexOfEnumerator("AppleType"); 
    QMetaEnum metaEnum = metaObject()->enumerator(index); 
    return metaEnum.valueToKey(apple); 
} 
2

Znacznie bardziej elegancki sposób znalazł (Qt 5.9), tylko jedną pojedynczą linię, za pomocą potężnego QVariant.

okazuje enum na ciąg:

QString theBig = QVariant::fromValue(ModelApple::Big).value<QString>(); 

Być może nie trzeba QMetaEnum więcej.

Przykładowy kod tutaj:

ModelApple (nie ma potrzeby zastrzeżenia Q_DECLARE_METATYE)

class ModelApple : public QObject 
{ 
    Q_OBJECT 
public: 
    enum AppleType { 
     Big, 
     Small 
    }; 
    Q_ENUM(AppleType) 
    explicit ModelApple(QObject *parent = nullptr); 
}; 

I utworzyć aplikację widget, wywołując funkcję QVaraint tam:

#include "mainwindow.h" 
#include "ui_mainwindow.h" 
#include <modelapple.h> 
#include <QDebug> 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    QString s = QVariant::fromValue(ModelApple::Big).value<QString>(); 
    qDebug() << s; 

} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

Widać, że Próbuję wypisać ciąg na konsoli, który tak naprawdę: enter image description here

Przepraszam za odwrotny rzut, próbowałem z powodzeniem w niektórych projektach, ale niektóre, jak tym razem poznałem błąd kompilacji. Więc postanowiłem usunąć to z mojej odpowiedzi.

+0

Dzięki za udzielenie odpowiedzi, wygląda na to, że metoda wymaga dodania 'Q_DECLARE_METATYPE (ModelApple :: AppleType)', a nawet dodana kompilacja zakończyła się sukcesem, wynikiem jest pusty ciąg znaków. Czy mógłbyś podać przykładowy kod do tego? – Jiu

+0

@ Na pewno sprawdź proszę, co edytowałem. –

0

Oto sposób bez użycia Q_ENUM makro

#define Enum2QStr(x) (QString(#x).split(“::”).at(1)) 

Pro: Twoje wyliczenia nie musi być insde dowolnej klasy (żaden członek Q_OBJECT lub Q_ENUM wymagane)