【问题标题】:QMetaEnum and strong typed enumQMetaEnum 和强类型枚举
【发布时间】:2016-01-17 20:17:16
【问题描述】:

使用普通枚举,我可以使用以下代码访问 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:我们仍在使用 qt4.8,但只要有时间就会切换到 qt5。
  • 我不太确定,但这可能与您的 Qt 版本有关。另外,检查stackoverflow.com/questions/6513736/…
  • @SingerOfTheFall:你是对的,根据你的链接 4.8 只支持 C++0x 的一些特性,强类型枚举不在其中。我尝试了 qt 5.2.1,它确实有效。

标签: c++ qt c++11 enums strong-typing


【解决方案1】:

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;
}

输出:

“A型”

【讨论】:

  • 根据您的链接,4.8 仅支持 C++0x 的某些功能,强类型枚举不在其中。我用 Q_ENUMS 尝试了 qt 5.2.1,因为 Q_ENUM 是在 qt 5.5 中引入的,它确实有效。谢谢!
【解决方案2】:

您可以将 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” “红色”“绿色”“蓝色”

【讨论】:

    【解决方案3】:

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

    对于 QObject 类,我们可以直接使用 QMetaEnum ,这种直接方法应该并且实际上有效,既获取 key 又获取 value ;测试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

    【讨论】:

      猜你喜欢
      • 2012-09-16
      • 1970-01-01
      • 2011-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多