Готовые методы реализаций

Преобразование полей enum в QString

обновлено 962 просмотров

Назначение

Для преобразования значений enum в строковое представление в Qt используется макрос Q_ENUM, который регистрирует перечисляемый тип в системе метаобъектов. Благодаря этому появляется возможность получать имена значений перечисления во время выполнения.

Требования к использованию

  • Q_ENUM должен быть помещён после объявления enum внутри класса.
  • Класс должен содержать макрос Q_OBJECT.
  • Перечисление должно быть объявлено в секции public.
  • Перечисления, объявленные с помощью Q_ENUM, имеют свой QMetaEnum, зарегистрированный во включающем объекте QMetaObject.
  • Получить QMetaEnum можно через QMetaEnum::fromType().

Функциональность доступна начиная с Qt 5.5.

Объявление перечисления

enum Priority { High, Low, VeryHigh, VeryLow };
Q_ENUM(Priority)

Здесь Priority — обычное перечисление, а Q_ENUM(Priority) регистрирует его в метасистеме Qt. Обратите внимание: макрос размещается сразу после объявления enum.

Шаблон для получения строковых значений

Универсальный шаблон, который работает с любым зарегистрированным enum:

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

Как это работает:

  1. QMetaEnum::fromType<QEnum>() — получает объект QMetaEnum для указанного типа.
  2. valueToKey(value) — возвращает строковое имя значения перечисления по его числовому эквиваленту.

Пример применения

QString test = QtEnumToString(Priority::High);
qDebug() << test;

В результате будет выведено строковое значение:

"High"

Важные замечания

  1. Без Q_ENUM преобразование невозможно. Если перечисление не зарегистрировано в метасистеме, valueToKey() вернёт nullptr, и строка окажется пустой.
  2. Q_ENUM требует Q_OBJECT. Макрос регистрирует перечисление в QMetaObject включающего класса, поэтому класс обязан наследоваться от QObject и содержать Q_OBJECT.
  3. Обратное преобразование. Для получения значения по строке используйте keyToValue():cppQMetaEnum metaEnum = QMetaEnum::fromType<Priority>(); Priority p = static_cast<Priority>(metaEnum.keyToValue(«High»));
  4. Q_ENUM vs Q_ENUMS. Устаревший макрос Q_ENUMS (множественное число) больше не нужен — Q_ENUM предоставляет более удобный API и работает с QMetaEnum::fromType().
  5. Q_ENUM vs Q_FLAG. Если перечисление используется как набор битовых флагов, применяйте Q_FLAG — он предоставляет дополнительные возможности (valueToKeys() и т. п.).
  6. Регистрация в QMetaType. Q_ENUM автоматически регистрирует перечисление как метатип, что позволяет использовать его в QVariant, сигналах и слотах.
  7. Область видимости. Перечисление, объявленное внутри класса с Q_ENUM, доступно как ClassName::Value, а также через метасистему.

Итог

Макрос Q_ENUM в связке с QMetaEnum::fromType() — простой и удобный способ преобразования значений enum в строки и обратно. Он требует наличия Q_OBJECT в классе и объявления перечисления в секции public. Универсальный шаблон QtEnumToString() позволяет использовать этот механизм для любых зарегистрированных перечислений, что делает код более читаемым и удобным для логирования и отладки.