QMetaEnum 和强类型枚举
QMetaEnum and strong typed enum
使用普通枚举,我可以使用以下代码访问 Q_ENUMS 属性和具体的枚举字符表示:
// in .h
class EnumClass : public QObject
{
Q_OBJECT
public:
enum MyEnumType { TypeA, TypeB };
Q_ENUMS(MyEnumType)
private:
MyEnumType m_type;
};
// in .cpp
m_type = TypeA;
...
const QMetaObject &mo = EnumClass::staticMetaObject;
int index = mo.indexOfEnumerator("MyEnumType");
QMetaEnum metaEnum = mo.enumerator(index);
QString enumString = metaEnum.valueToKey(m_type); // contains "TypeA"
如果我想将 c++11 功能用于 强类型枚举 ,例如
enum class MyEnumType { TypeA, TypeB };
访问元信息不再有效。我想,Qt 不再将其识别为枚举了。
在使用强类型枚举时,是否有任何解决方案来访问枚举的字符表示?
Q_ENUMS
已过时,应改用 Q_ENUM
,但以下代码对我来说适用于它们中的任何一个(Qt 5.5,您的问题可能是由旧的 Qt 版本引起的; this question 也是相关的):
.h:
#include <QObject>
class EnumClass : public QObject
{
Q_OBJECT
public:
enum class MyEnumType { TypeA, TypeB };
EnumClass();
Q_ENUM(MyEnumType)
private:
MyEnumType m_type;
};
.cpp:
#include <QDebug>
#include <QMetaEnum>
#include <QMetaObject>
EnumClass::EnumClass()
{
m_type = MyEnumType::TypeA;
const QMetaObject &mo = EnumClass::staticMetaObject;
int index = mo.indexOfEnumerator("MyEnumType");
QMetaEnum metaEnum = mo.enumerator(index);
// note the explicit cast:
QString enumString = metaEnum.valueToKey(static_cast<int>(m_type));
qDebug() << enumString;
}
主要内容:
int main()
{
EnumClass asd;
return 0;
}
输出:
"TypeA"
您可以在 QMetaEnum 中使用 Q_ENUM 宏和模板:
in.h:
#pragma once
#include <QObject>
#include <QString>
#include <QMetaEnum>
template<typename T>
QString enumToString(T value)
{
int castValue = static_cast<int>(value);
return QMetaEnum::fromType<T>().valueToKey(castValue);
}
class Enum : public QObject
{
Q_OBJECT
public:
enum class Color {
NO_COLOR = 0,
RED,
GREEN,
BLUE,
};
Q_ENUM(Color)
Enum();
Enum(Color color);
QString toString();
private:
Color m_value {Color::NO_COLOR};
};
in.cpp:
#include "in.h"
Enum::Enum()
{
}
Enum::Enum(Color color = Color::NO_COLOR) : m_value(color)
{
}
QString Enum::toString()
{
return enumToString(m_value);
}
main.cpp
#include "in.h"
#include <QDebug>
int main()
{
Enum none;
Enum red(Enum::Color::RED);
Enum green(Enum::Color::GREEN);
Enum blue(Enum::Color::BLUE);
qDebug() << none.toString();
qDebug() << red.toString() << green.toString() << blue.toString();
return 0;
}
输出:
"NO_COLOR"
"RED" "GREEN" "BLUE"
使用 enum class
时,将类型转换为 int
in valueToKey()
:
对于 QObject
class ,我们可以直接使用 QMetaEnum
,这种直接的方法应该并且确实有效,同时获取键和值;测试 Qt_5_10
声明:
class EnumClass : public QObject
{
Q_OBJECT
public:
enum class MyEnumType { TypeA, TypeB };
Q_ENUM(MyEnumType)
...
};
用法:
QMetaEnum metaEnum = QMetaEnum::fromType<EnumClass::MyEnumType>();
qDebug() << metaEnum.valueToKey(static_cast<int>(EnumClass::MyEnumType::TypeA));
qDebug() << metaEnum.keyToValue("TypeB");
...
结果:
“类型 A”
1
使用普通枚举,我可以使用以下代码访问 Q_ENUMS 属性和具体的枚举字符表示:
// in .h
class EnumClass : public QObject
{
Q_OBJECT
public:
enum MyEnumType { TypeA, TypeB };
Q_ENUMS(MyEnumType)
private:
MyEnumType m_type;
};
// in .cpp
m_type = TypeA;
...
const QMetaObject &mo = EnumClass::staticMetaObject;
int index = mo.indexOfEnumerator("MyEnumType");
QMetaEnum metaEnum = mo.enumerator(index);
QString enumString = metaEnum.valueToKey(m_type); // contains "TypeA"
如果我想将 c++11 功能用于 强类型枚举 ,例如
enum class MyEnumType { TypeA, TypeB };
访问元信息不再有效。我想,Qt 不再将其识别为枚举了。
在使用强类型枚举时,是否有任何解决方案来访问枚举的字符表示?
Q_ENUMS
已过时,应改用 Q_ENUM
,但以下代码对我来说适用于它们中的任何一个(Qt 5.5,您的问题可能是由旧的 Qt 版本引起的; this question 也是相关的):
.h:
#include <QObject>
class EnumClass : public QObject
{
Q_OBJECT
public:
enum class MyEnumType { TypeA, TypeB };
EnumClass();
Q_ENUM(MyEnumType)
private:
MyEnumType m_type;
};
.cpp:
#include <QDebug>
#include <QMetaEnum>
#include <QMetaObject>
EnumClass::EnumClass()
{
m_type = MyEnumType::TypeA;
const QMetaObject &mo = EnumClass::staticMetaObject;
int index = mo.indexOfEnumerator("MyEnumType");
QMetaEnum metaEnum = mo.enumerator(index);
// note the explicit cast:
QString enumString = metaEnum.valueToKey(static_cast<int>(m_type));
qDebug() << enumString;
}
主要内容:
int main()
{
EnumClass asd;
return 0;
}
输出:
"TypeA"
您可以在 QMetaEnum 中使用 Q_ENUM 宏和模板:
in.h:
#pragma once
#include <QObject>
#include <QString>
#include <QMetaEnum>
template<typename T>
QString enumToString(T value)
{
int castValue = static_cast<int>(value);
return QMetaEnum::fromType<T>().valueToKey(castValue);
}
class Enum : public QObject
{
Q_OBJECT
public:
enum class Color {
NO_COLOR = 0,
RED,
GREEN,
BLUE,
};
Q_ENUM(Color)
Enum();
Enum(Color color);
QString toString();
private:
Color m_value {Color::NO_COLOR};
};
in.cpp:
#include "in.h"
Enum::Enum()
{
}
Enum::Enum(Color color = Color::NO_COLOR) : m_value(color)
{
}
QString Enum::toString()
{
return enumToString(m_value);
}
main.cpp
#include "in.h"
#include <QDebug>
int main()
{
Enum none;
Enum red(Enum::Color::RED);
Enum green(Enum::Color::GREEN);
Enum blue(Enum::Color::BLUE);
qDebug() << none.toString();
qDebug() << red.toString() << green.toString() << blue.toString();
return 0;
}
输出:
"NO_COLOR" "RED" "GREEN" "BLUE"
使用 enum class
时,将类型转换为 int
in valueToKey()
:
对于 QObject
class ,我们可以直接使用 QMetaEnum
,这种直接的方法应该并且确实有效,同时获取键和值;测试 Qt_5_10
声明:
class EnumClass : public QObject
{
Q_OBJECT
public:
enum class MyEnumType { TypeA, TypeB };
Q_ENUM(MyEnumType)
...
};
用法:
QMetaEnum metaEnum = QMetaEnum::fromType<EnumClass::MyEnumType>();
qDebug() << metaEnum.valueToKey(static_cast<int>(EnumClass::MyEnumType::TypeA));
qDebug() << metaEnum.keyToValue("TypeB");
...
结果:
“类型 A”
1