QMetaEnum和强类型枚举

7

使用普通枚举类型,我能够通过以下代码访问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不再将其识别为枚举。

在使用强类型枚举时,有没有办法访问枚举的字符表示?


你使用的是哪个Qt版本? - SingerOfTheFall
@SingerOfTheFall:我们目前仍在使用Qt4.8,但是一旦有时间,我们将会转换到Qt5。 - agentsmith
我不是完全确定,但这可能是由于您的Qt版本。另外,请检查https://dev59.com/mFjUa4cB1Zd3GeqPT7iP - SingerOfTheFall
@SingerOfTheFall:你说得对,根据你提供的链接,4.8版本只支持C++0x的一些特性,强类型枚举不在其中。我尝试了Qt 5.2.1,它可以工作。 - agentsmith
3个回答

4

Q_ENUMS已过时,应使用Q_ENUM代替,但以下代码对我来说均可使用(Qt 5.5,您的问题可能是由旧版Qt版本引起的;此外这个问题是相关的):

.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"


根据您提供的链接,4.8版本仅支持C++0x的某些功能,强类型枚举不在其中。我尝试了使用带有Q_ENUMS的qt 5.2.1,因为Q_ENUM是在qt 5.5中引入的,它确实可以工作。谢谢! - agentsmith

1

您可以使用Q_ENUM宏和带有QMetaEnum的模板:

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"


0

在使用enum class时,在valueToKey()中将类型转换为int

对于一个QObject类,我们可以直接使用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");

...

结果:

"TypeA"

1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接