How can we declare enumerations in QML, without any JavaScript?
You can use a pure Qml singleton, so you don't need any C++ or javascript.
colors/MyColors.qml:
pragma Singleton
import QtQuick 2.5
QtObject {
id: singleton
property int red: 0
property int green: 1
property int blue: 2
}
colors/qmldir:
singleton MyColors 1.0 MyColors.qml
Your qml file:
import "colors" 1.0
// MyColors.red
// MyColors.green
// MyColors.blue
Since Qt 5.10, enumerations are directly supported in QML. See Qt documentation which contains sample code.
You can define one with the enum
keyword. The type and its values must start with a capital letter but otherwise follow rules for naming a variable (e.g. can include digits and underscore).
To use the enum, you have to explicitly include the full scope including the component ComponentName.EnumType.EnumValue
. This is true even when using it within the component itself.
e.g.
// MyComponent.qml
Rectangle {
id: root
// Define Shape enum
enum Shape {
None,
Round,
Pointy,
Bobbly,
Elusive
}
// Note: property using enum is of type int
property int selectedShape: MyComponent.Shape.None
visible: selectedShape !== MyComponent.Shape.None
color: selectedShape === MyComponent.Shape.Pointy? "red": "green"
}
Note that enumerated values are treated as int
and you can assign and compare them as such.
Although not documented (and therefore potentially subject to change), by default the first one has value 0
, the second 1
, etc.. However you can assign a non-negative integer value. You can even assign two enum values to the same integer value though that is probably not a good idea. You cannot assign an expression that evaluates to an integer.
e.g.
enum Shape {
None = 5, // valid
Round, // automatically assigned 6
Pointy = -1, // not valid
Bobbly = Round // not valid
Elusive = (8-7) // not valid
}
Thanks to Michael Brasser's blog comment about assigning simple values.
First, use enum class
instead of enum
for better type safety
enum class Color { RED, GREEN, BLUE };
Color r = Color::RED;
Then register it for Qt using Q_ENUMS
(use Q_ENUM
for Qt 5.5+):
mycolors.h
#pragma once
#include <QObject>
class MyColors : public QObject
{
Q_OBJECT
public:
enum class Color {
RED,
GREEN,
BLUE
};
Q_ENUMS(Color)
static void init();
};
To make the enum available in QML, register it (in a mycolors.cpp file):
void MyColors::init()
{
qRegisterMetaType<MyColors::Color>("MyColors::Color");
qmlRegisterType<MyColors>("MyQmlModule", 1, 0, "MyColors");
}
and call Colors::init()
in your main()
.
In QML you now have
import MyQmlModule 1.0
// MyColors.RED
// MyColors.GREEN
// MyColors.BLUE