QMetaEnum and strong typed enum
Asked Answered
T

3

7

With plain enums I was able to access Q_ENUMS properties and specific, the character represenation of enums, with following code:

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

If I want to use the c++11 feature for strong typed enums like

enum class MyEnumType { TypeA, TypeB };

accessing the meta information does not work anymore. I guess, that Qt does not recognize it as an enum anymore.

Is there any solution to access the character represenation of an enum while using strong typed enums?

Tetherball answered 19/10, 2015 at 13:3 Comment(4)
Which Qt version are you using?Mehetabel
@SingerOfTheFall: we are using still qt4.8, but are going to switch to qt5 whenever we find the time for that.Tetherball
I'm not entirely sure, but this may be because of your Qt version. Also, check #6514236Mehetabel
@SingerOfTheFall: you are right, according to your link 4.8 does only support some features of C++0x, strong typed enums is not among those. I tried qt 5.2.1 and it did work.Tetherball
M
4

Q_ENUMS is obsolete, and Q_ENUM should be used instead, but the following code works for me with either of them (Qt 5.5, your issue might be caused by an old Qt version; also this question is relevant):

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

main:

int main()
{
    EnumClass asd;
    return 0;
}

output:

"TypeA"

Mehetabel answered 19/10, 2015 at 13:20 Comment(1)
According to your link 4.8 does only support some features of C++0x, strong typed enums is not among those. I tried qt 5.2.1 with Q_ENUMS, since Q_ENUM was introduced with qt 5.5, and it does work. Thanks!Tetherball
M
1

You can use Q_ENUM macro and template with 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;
}

output:

"NO_COLOR" "RED" "GREEN" "BLUE"

Mythopoeic answered 9/10, 2020 at 11:24 Comment(0)
M
0

When using enum class , cast the type to int in valueToKey():

For a QObject class , we ca directly use QMetaEnum , this direct approach should and actually works, both getting key and value ; tested Qt_5_10

declaration:

class EnumClass : public QObject
{
  Q_OBJECT
public:
  enum class MyEnumType { TypeA, TypeB };
  Q_ENUM(MyEnumType)
...
};

Usage:

   QMetaEnum metaEnum = QMetaEnum::fromType<EnumClass::MyEnumType>();
   qDebug() << metaEnum.valueToKey(static_cast<int>(EnumClass::MyEnumType::TypeA));
   qDebug() << metaEnum.keyToValue("TypeB");

...

result :

"TypeA"

1

Mesopotamia answered 14/6, 2021 at 9:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.