Reputation: 327
I want to use the elements of an enum as items in a QComboBox. I can do so if the enum is defined in the same class but I would like to use an enum defined in a header file. My goal is to use the enum directly from the header file, without altering the header file. Moreover, I would like my code to adapt to a changing enum, both in the name of the elements and in the number of them.
I have found this answer and this link that have helped me understand how to populate a QComboBox with an enum. The solution in the answer works for me but only if the enum is defined in the class.
The basic code I would like to implement looks like:
definitions.h
#ifndef _DEFINITIONS_H_
#define _DEFINITIONS_H_
typedef enum
{
FIRST = 0,
SECOND,
THIRD
} elements;
#endif
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "definitions.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
Q_ENUMS(elements);
public:
explicit MainWindow(QWidget *parent = 0);
QComboBox *comboBox;
};
#endif
mainwindow.cc
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
{
int index = metaObject()->indexOfEnumerator("elements");
QMetaEnum metaEnum = metaObject()->enumerator(index);
for (int i = 0; i < metaEnum.keyCount(); i++)
comboBox->addItem(metaEnum.valueToKey(i));
}
This code does not encounter any issue at compilation on runtime but has no effect at all. Defining the enum in MainWindow class works like a charm.
It does not look like a visibility issue because I can use the elements of the enum in my code and I have not encountered any compilation problem.
I have tried redefining my enum in mainwindow.h with typedef without success:
typedef elements new_elements
I have also tried replacing Q_ENUMS
with Q_ENUM
as suggested by the answer below but the result is the same.
Is it possible to use Q_ENUMS/Q_ENUM with an enum defined in a header file? What should I do different?
Upvotes: 1
Views: 2859
Reputation: 4050
You can't do that. Q_ENUMS
need a meta object provided either by the QObject
class or the Q_GADGET
macro, that's why it works when the enum is declared in a class derived from a QObject
.
Since Qt 5.8, a new macro was introduced Q_ENUM_NS
that makes this possible:
This macro registers an enum type with the meta-object system. It must be placed after the enum declaration in a namespace that has the Q_NAMESPACE macro. It is the same as Q_ENUM but in a namespace.
You can do something like that:
namespace MyNamespace {
Q_NAMESPACE
enum elements {
FIRST = 0,
SECOND,
THIRD
};
Q_ENUM_NS(elements)
}
See this post for more information.
Regarding the last comment, you can create a new enumeration and associate each element with the value of the new one.
class MainWindow : public QMainWindow {
Q_OBJECT
public:
enum elements {
FIRST = ::elements::FIRST,
SECOND = ::elements::SECOND,
THIRD = ::elements::THIRD,
};
Q_ENUM(elements);
}
Then, for a function like:
void use_enum(elements e);
// Call it with the original one
use_enum(elements::FIRST);
// Call it with the new one, you just created
use_enum(MainWindow::elements::FIRST);
Upvotes: 1
Reputation: 208
Check the Q_ENUM that registers automatically as metatype as it is said in the documentation What's New in Qt 5.5:
Added Q_ENUM to replace Q_ENUMS, which allows to get a QMetaEnum at compile time using QMetaEnum::fromType. Such enums are now automatically registered as metatypes, and can be converted to strings within QVariant, or printed as string by qDebug().
Upvotes: 0