Есть ли способ использовать QMetaEnum с Q_ENUMS, принадлежащим не классу Q_OBJECT или Q_GADGET?
Например, у меня есть следующий класс:
namespace someName
{
class someClass
{
Q_ENUMS(ESomeEnum)
public:
enum ESomeEnum {ENUM_A, ENUM_B, ENUM_C};
// ... some other things ..
}
}
Q_DECLARE_METATYPE(someName::someClass)
Есть ли способ использовать QMetaEnum::valueToKey или QMetaEnum::keyToValue?
Попробовал метод в этом ответе, но получил следующую ошибку:
error: static assertion failed: QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG #define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
Я могу использовать X-Macros для получения желаемого результата, но было бы неплохо узнать больше трюков в Qt.
2 ответа
Нет, потому что нет Q_ENUM
Функциональность реализована в коде, сгенерированном moc, и moc игнорирует классы, которые не являются Q_OBJECT
ни Q_GADGET
, Там нет причин, чтобы не использовать Q_GADGET
поскольку он не влияет на размер объекта: не добавляет ни виртуальных методов, ни полей данных.
Следующее демонстрирует это:
#include <QtCore>
namespace Ns {
class Class {
Q_GADGET
public:
enum ESomeEnum {ENUM_A, ENUM_B, ENUM_C};
Q_ENUM(ESomeEnum)
};
}
int main() {
auto metaEnum = QMetaEnum::fromType<Ns::Class::ESomeEnum>();
qDebug() << sizeof(Ns::Class) << metaEnum.valueToKey(Ns::Class::ENUM_A);
}
#include "main.moc"
Выход:
1 ENUM_A
На этой конкретной платформе (и многих других) пустые классы имеют размер 1.
Да, с 5.8 вы можете сделать:
namespace MyLibrary
{
Q_NAMESPACE
enum class MYLIBRARYSHARED_EXPORT MyEnumClass
{
...
};
Q_ENUM_NS(MyEnumClass)
...
} // namespace MyLibrary
Q_ENUM
как старый Q_ENUMS
но с этими различиями:
- Это должно быть размещено после
enum
в исходном коде. - Только один
enum
можно положить в макрос. - Это позволяет
QMetaEnum::fromType<T>()
, - Эти
enum
s автоматически объявляются какQMetaType
s (нет необходимости добавлять их вQ_DECLARE_METATYPE
больше). enum
с переданыqDebug
напечатает имя значения, а не число.- Когда положить в
QVariant
,toString()
дает имя значения. Имя значения напечатаноQCOMPARE
(начиная с Qt 5.6)
Взято из блога WOBOQ по теме, прочитайте его для получения дополнительной информации относительно Q_ENUM
против Q_ENUMS
,