读QT5.7源码(五)QMetaEnum

Enum在QMetaObject中的分布:



QMetaEnum   类用来管理对应的enum结构,方面查询等操作,下面是它的定义

class Q_CORE_EXPORT QMetaEnum
{
public:
    Q_DECL_CONSTEXPR inline QMetaEnum() : mobj(Q_NULLPTR), handle(0) {}

    const char *name() const;
    bool isFlag() const;

    int keyCount() const;
    const char *key(int index) const;
    int value(int index) const;

    const char *scope() const;

    int keyToValue(const char *key, bool *ok = Q_NULLPTR) const;
    const char* valueToKey(int value) const;
    int keysToValue(const char * keys, bool *ok = Q_NULLPTR) const;
    QByteArray valueToKeys(int value) const;

    inline const QMetaObject *enclosingMetaObject() const { return mobj; }

    inline bool isValid() const { return name() != Q_NULLPTR; }

    template<typename T> static QMetaEnum fromType() {
        Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value,
                          "QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG");
        const QMetaObject *metaObject = qt_getEnumMetaObject(T());
        const char *name = qt_getEnumName(T());
        return metaObject->enumerator(metaObject->indexOfEnumerator(name));
    }

private:
    const QMetaObject *mobj;
    uint handle;
    friend struct QMetaObject;
};

    const QMetaObject *mobj;  
    uint handle;


所有的操作基于这两个成员,hadnle 是该枚举节 相对整个结构的偏移量



1、const char *QMetaEnum::name() const       返回枚举类型的名称字符串

const char *QMetaEnum::name() const
{
    if (!mobj)
        return 0;
    return rawStringData(mobj, mobj->d.data[handle]);
}

2、int QMetaEnum::keyCount() const   返回Key的数量

int QMetaEnum::keyCount() const
{
    if (!mobj)
        return 0;
    return mobj->d.data[handle + 2];  枚举节的第三个int值是Key的数量
}


3、const char *QMetaEnum::key(int index) const   返回index索引的Key的名称字符串

const char *QMetaEnum::key(int index) const
{
    if (!mobj)
        return 0;
    int count = mobj->d.data[handle + 2];   数量
    int data = mobj->d.data[handle + 3];    Key节的偏移
    if (index >= 0  && index < count)
        return rawStringData(mobj, mobj->d.data[data + 2*index]); 每个Key节 两个Int
    return 0;
}

4、int QMetaEnum:: value (int index) const    返回index索引的Key的值
int QMetaEnum::value(int index) const
{
    if (!mobj)
        return 0;
    int count = mobj->d.data[handle + 2];
    int data = mobj->d.data[handle + 3];
    if (index >= 0  && index < count)
        return mobj->d.data[data + 2*index + 1]; Key节的第二个Int是其值
    return -1;
}

5、 bool QMetaEnum:: isFlag() const       是否使用标记

/*!
    Returns \c true if this enumerator is used as a flag; otherwise returns
    false.

    When used as flags, enumerators can be combined using the OR
    operator.

    \sa keysToValue(), valueToKeys()
*/
bool QMetaEnum::isFlag() const
{
    return mobj && mobj->d.data[handle + 1];
}


6、const char *QMetaEnum::scope() const  返回所属类名

const char *QMetaEnum::scope() const
{
    return mobj ? objectClassName(mobj) : 0;
}

7、int QMetaEnum:: keyToValue (const char *key, bool *ok) const  根据Key名返回对应的值



int QMetaEnum::keyToValue(const char *key, bool *ok) const
{
    if (ok != 0)
        *ok = false;
    if (!mobj || !key)
        return -1;
    uint scope = 0;
    const char *qualified_key = key;
    const char *s = key + qstrlen(key);
    while (s > key && *s != ':')
        --s;
    if (s > key && *(s-1)==':') {
        scope = s - key - 1;
        key += scope + 2;
    }
    int count = mobj->d.data[handle + 2];
    int data = mobj->d.data[handle + 3];
    for (int i = 0; i < count; ++i) {
        const QByteArray className = stringData(mobj, priv(mobj->d.data)->className);
        if ((!scope || (className.size() == int(scope) && strncmp(qualified_key, className.constData(), scope) == 0))
             && strcmp(key, rawStringData(mobj, mobj->d.data[data + 2*i])) == 0) {
            if (ok != 0)
                *ok = true;
            return mobj->d.data[data + 2*i + 1];
        }
    }
    return -1;
}

8、const char* QMetaEnum::valueToKey(int value) const  根据值返回Key 名


const char* QMetaEnum::valueToKey(int value) const
{
    if (!mobj)
        return 0;
    int count = mobj->d.data[handle + 2];
    int data = mobj->d.data[handle + 3];
    for (int i = 0; i < count; ++i)
        if (value == (int)mobj->d.data[data + 2*i + 1])
            return rawStringData(mobj, mobj->d.data[data + 2*i]);
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值