Как конвертировать enum в QString?

Я пытаюсь использовать отражение Qt для преобразования enum в QString.

Вот часть кода:

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

И вот я пытаюсь сделать:

convertEnumToQString(ModelApple::Big)

Вернуть "Big"

Это возможно? Если у вас есть идеи о convertEnumToQStringпожалуйста поделитесь

6 ответов

Решение

Вам нужно использовать макрос Q_ENUM, который регистрирует тип enum в системе мета-объектов.

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

И теперь вы можете использовать класс QMetaEnum для доступа к метаданным о перечислителе.

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

Вот общий шаблон для такой утилиты:

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

Найден гораздо более элегантный способ (Qt 5.9), всего одна строчка, с помощью могущественного QVariant.

превращает enum в строку:

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

Возможно, вам больше не нужен QMetaEnum.

Пример кода здесь:

ModelApple (не нужно требовать Q_DECLARE_METATYE)

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

И я создаю приложение виджета, вызывая там функцию QVaraint:

#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;
}

Вы можете видеть, что я пытаюсь вывести строку на консоль, которая действительно сделала:

И извините за обратное приведение, я попытался успешно в каком-то проекте, но кое-как, как в этот раз я встретил ошибку компиляции. Поэтому я решил удалить его из своего ответа.

Следующее должно помочь вам:

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

Для глобального объявления Enum используйте это в любом заголовочном файле:

namespace YourNamespace {

Q_NAMESPACE

enum YourEnum: int {

    EnumValue1,
    EnumValue2
};
Q_ENUM_NS(YourEnum)

}

и здесь вы хотите получить описание Enum:

QMetaEnum metaEnum = QMetaEnum::fromType<YourEnum>();
qDebug() << "Enum description: " << metaEnum.name() << "::" << metaEnum.valueToKey(YourEnum::EnumValue2);

Как насчет:

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

ОБНОВЛЕНО: для Qt 5.5 смотрите этот ответ

Я столкнулся с той же проблемой, и вот как я ее решил. Это особенно для 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);
}

Вот способ без использования макроса Q_ENUM

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

Pro: Ваше перечисление не должно быть insde какого-либо класса (не требуется член Q_OBJECT или Q_ENUM)

Минусы: нельзя использовать с переменной

Другие вопросы по тегам