(1)类 QMetaEnum 的定义,包含 #include 《QMetaProperty》 即可找到:
先看一下本类概述:

++ 源码:
class Q_CORE_EXPORT QMetaEnum //本类提供有关枚举器的元数据。
{
private:
struct Data {
enum { Size = 5 };
const uint * d;
quint32 name() const { return d[0]; }
quint32 alias() const { return d[1]; }
quint32 flags() const { return d[2]; }
qint32 keyCount() const { return static_cast<qint32>(d[3]); }
quint32 data() const { return d[4]; }
};
Data data; //本元枚举类定义的数据成员
const QMetaObject * mobj;
QMetaEnum(const QMetaObject *mobj, int index); //构造函数
friend struct QMetaObject;
friend struct QMetaObjectPrivate;
public: //默认初始化数据成员为控制
constexpr inline QMetaEnum() : mobj(nullptr), data({ nullptr }) {}
const char * name() const; //返回类型的名称(不包括作用域)
//例如,Qt::Key 枚举的类型名为 Key,作用域为 Qt。
//对于标志,它返回标志类型的名称,而不是枚举类型的名称。
const char * enumName() const;//返回标志的枚举名称(不包括范围)
//例如,Qt:AlignmentFlag标志具有 AlignmentFlag作为枚举名称,但 Alignment作为类型名称。
//非标志枚举具有相同的类型和枚举名称。枚举名称与类型名称具有相同的范围。
bool isFlag() const; //如果此枚举器用作标志,则返回 true;否则返回 false。
//当用作标志时,枚举器可以使用 OR 运算符组合。
bool isScoped() const; //若此枚举器声明为 C++11枚举类,则返回 true;否则返回 false。
const char * scope() const; //返回枚举者声明的上下文范围。scope 范围
//列如,Qt::AlignmentFlag 枚举的别名 scope 是 Qt,名称是 AlignmentFlag。
inline bool isValid() const { return name() != nullptr; }
//如果此枚举有效(具有名称),则返回true;否则返回 false。
int keyCount() const; // Returns the number of keys.
const char * key(int index) const;
//Returns the key with the given index, or nullptr if no such key exists
int value(int index) const;
//Returns the value with the given index; or returns -1 if there is no such value.
int keyToValue(const char * key, bool * ok = nullptr) const; // ok用于返回值
//返回给定枚举键的整数值,如果键未定义则返回-1。 // a=5 则 key = a,value = 5
//如果未定义 key,则 *ok 设置为 false;否则 *ok 设置为 true。
int keysToValue(const char *keys, bool *ok = nullptr) const; //带 flag 标志
//返回使用 OR 运算符将键的值组合在一起得出的值,如果键未定义则为-1。
//请注意,键中的字符串必须以“|”分隔。 keys 包含多个字符串,之间以 | 分割
//如果未定义 keys,则 *ok 设置为 false;否则 *ok 设置为 true。
const char * valueToKey(int value) const; //适用于普通枚举
//返回用作给定枚举值的名称的字符串,如果未定义值则为 nullptr。
QByteArray valueToKeys(int value) const;//要求枚举同时用 Q_FLAG声明,以支持位运算。
//返回一个以 | 分隔的字节数组,表示给定的值。因为会返回被 or 运算组合到一起的多个名字
//Returns a byte array of '|'-separated keys that represents the given value.
//返回内部包裹的 QMetaObject * 数据成员
inline const QMetaObject * enclosingMetaObject() const { return mobj; }
//返回与模板参数类型相对应的 QMetaEnum。枚举需要使用 QENUM进行声明。
template<typename T>
static QMetaEnum fromType() //静态成员函数,返回值还是本类型
{
static_assert(QtPrivate::IsQEnumHelper<T>::Value,
"QMetaEnum::fromType only works with enums declared as "
"Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS");
const QMetaObject * metaObject = qt_getEnumMetaObject(T());
const char * name = qt_getEnumName(T());
return metaObject->enumerator(metaObject->indexOfEnumerator(name));
}
};
Q_DECLARE_TYPEINFO(QMetaEnum, Q_RELOCATABLE_TYPE);
(2)解释下上面源码里出现的宏 Q_DECLARE_TYPEINFO ,先给出其官方的英文注释:

++ 给出其源码:
/* Specialize a specific type with: Q_DECLARE_TYPEINFO(type, flags);
where 'type' is the name of the type to specialize and 'flags' is
logically-OR'ed combination of the flags below.*/
enum { /* TYPEINFO flags */
Q_COMPLEX_TYPE = 0,
Q_PRIMITIVE_TYPE = 0x1,
Q_RELOCATABLE_TYPE = 0x2,
Q_MOVABLE_TYPE = 0x2,
Q_DUMMY_TYPE = 0x4,
};
#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \
class QTypeInfo<TYPE > \
{ \
public: \
enum { \
isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && !std::is_trivial_v<TYPE>, \
isRelocatable = !isComplex || ((FLAGS) & Q_RELOCATABLE_TYPE) || qIsRelocatable<TYPE>, \
isPointer = false, \
isIntegral = std::is_integral< TYPE >::value, \
}; \
}
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
template<> \
Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)
/* Specialize QTypeInfo for QFlags<T> */
template<typename T>
class QFlags;
template<typename T> // 此模板函数已经没有定义了,跟踪到此为止,但结合注释也够用了
Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE);
(3)
谢谢
1418

被折叠的 条评论
为什么被折叠?



