Назначение
Для преобразования значений 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));
}
Как это работает:
QMetaEnum::fromType<QEnum>()— получает объектQMetaEnumдля указанного типа.valueToKey(value)— возвращает строковое имя значения перечисления по его числовому эквиваленту.
Пример применения
QString test = QtEnumToString(Priority::High);
qDebug() << test;
В результате будет выведено строковое значение:
"High"
Важные замечания
- Без
Q_ENUMпреобразование невозможно. Если перечисление не зарегистрировано в метасистеме,valueToKey()вернётnullptr, и строка окажется пустой. Q_ENUMтребуетQ_OBJECT. Макрос регистрирует перечисление вQMetaObjectвключающего класса, поэтому класс обязан наследоваться отQObjectи содержатьQ_OBJECT.- Обратное преобразование. Для получения значения по строке используйте
keyToValue():cppQMetaEnum metaEnum = QMetaEnum::fromType<Priority>(); Priority p = static_cast<Priority>(metaEnum.keyToValue(«High»)); Q_ENUMvsQ_ENUMS. Устаревший макросQ_ENUMS(множественное число) больше не нужен —Q_ENUMпредоставляет более удобный API и работает сQMetaEnum::fromType().Q_ENUMvsQ_FLAG. Если перечисление используется как набор битовых флагов, применяйтеQ_FLAG— он предоставляет дополнительные возможности (valueToKeys()и т. п.).- Регистрация в
QMetaType.Q_ENUMавтоматически регистрирует перечисление как метатип, что позволяет использовать его вQVariant, сигналах и слотах. - Область видимости. Перечисление, объявленное внутри класса с
Q_ENUM, доступно какClassName::Value, а также через метасистему.
Итог
Макрос Q_ENUM в связке с QMetaEnum::fromType() — простой и удобный способ преобразования значений enum в строки и обратно. Он требует наличия Q_OBJECT в классе и объявления перечисления в секции public. Универсальный шаблон QtEnumToString() позволяет использовать этот механизм для любых зарегистрированных перечислений, что делает код более читаемым и удобным для логирования и отладки.