7

For example I have the following class:

namespace someName
{
    class someClass
    {
        Q_ENUMS(ESomeEnum)

        public:
        enum ESomeEnum {ENUM_A, ENUM_B, ENUM_C};

        // ... some other things ..
    }
}

Q_DECLARE_METATYPE(someName::someClass)

Is there a way to use QMetaEnum::valueToKey or QMetaEnum::keyToValue ?

Tried the method in this answer but got the following error:

error: static assertion failed: QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG
#define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)

I can employ X-Macros to get my desired output but it would also be nice to learn more tricks in Qt.

Community
  • 1
  • 1
misilita
  • 73
  • 1
  • 3
  • You are using `Q_ENUMS`, I think you have to use `Q_ENUM` in this case. – thuga Jun 07 '16 at 10:59
  • i am maintaining code written in this manner and changing Q_ENUMS to Q_ENUM would flag unnecessary "panic" to the project manager as this affects a lot of files. – misilita Jun 08 '16 at 02:00
  • As of right now, the accepted answer should be different. @DrumM is correct, since Qt 5.8 you could use `Q_NAMESPACE` + `Q_ENUM_NS` combo. – sthlm58 Jan 22 '20 at 10:41

3 Answers3

9

No, there isn't, because Q_ENUM's functionality is implemented in code generated by moc, and moc ignores classes that are neither Q_OBJECT nor Q_GADGET. There's no reason for not using a Q_GADGET since it has no effect on object size: adds no virtual methods nor data fields.

The following demonstrates this:

#include <QtCore>

namespace Ns {
class Class {
   Q_GADGET
public:
   enum ESomeEnum {ENUM_A, ENUM_B, ENUM_C};
   Q_ENUM(ESomeEnum)
};
}

int main() {
   auto metaEnum = QMetaEnum::fromType<Ns::Class::ESomeEnum>();
   qDebug() << sizeof(Ns::Class) << metaEnum.valueToKey(Ns::Class::ENUM_A);
}
#include "main.moc"

Output:

1 ENUM_A

On this particular platform (and many others), empty classes are of size 1.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
5

Yes, since 5.8 you can do:

namespace MyLibrary
{ 
Q_NAMESPACE 

enum class MYLIBRARYSHARED_EXPORT MyEnumClass
{
...
}; 

Q_ENUM_NS(MyEnumClass)

...
} // namespace MyLibrary
jaques-sam
  • 2,578
  • 1
  • 26
  • 24
4

Q_ENUM is like the old Q_ENUMS but with these differences:

  • It needs to be placed after the enum in the source code.
  • Only one enum can be put in the macro.
  • It enables QMetaEnum::fromType<T>().
  • These enums are automatically declared as a QMetaTypes (no need to add them in Q_DECLARE_METATYPE anymore).
  • enums passed to qDebug will print the name of the value rather than the number.
  • When put in a QVariant, toString() gives the value name. The value name is printed by QCOMPARE (since Qt 5.6)

Taken from WOBOQ blog post on the topic, read it for additional information regarding Q_ENUM vs Q_ENUMS.

BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
ManuelH
  • 846
  • 1
  • 15
  • 25