Déclaration de la classe qui hérite de QObject
dans les fichiers .cpp
/.hpp
:
- Macro
Q_OBJECT
: déclare le méta-type pour la classeMyObject
. - Macro
Q_ENUM
: déclare les infos nécessaires pour l'enumMyEnum
. - Une fonction statique
init()
qui déclare le typeMyObject
à QML.
#pragma once
#include <QObject>
#include <QtQml/qqml.h>
namespace my::namespace {
class MyQObject : public QObject {
Q_OBJECT
Q_PROPERTY(my::namespace::MyEnum myEnum READ myEnum WRITE setMyEnum)
public:
enum class MyEnum {
Foo,
Bar,
};
Q_ENUM(MyEnum)
public:
// ctor...
// A mettre dans le .cpp
static void init() {
qmlRegisterType<MyQObject>("My.Namespace", // QML import statement
1, // Major version of QML import
0, // Minor version of QML import
"MyObject"); // name in QML
}
};
}
Dans main.cpp
(ou n'importe où avant la création de l'engine QML) :
my::namespace::MyQObject::init();
Utilisation de l'enum class
C++ en QML:
- QML représente toujours les enums sous forme d'
int
. Si on faitconsole.log(MyQObject.MyEnum.Bar)
, cela affiche1
. - Les property QML qui l'utilisent doivent être de type
int
. - Si on veut l'afficher sous forme de
string
, il faut faire soi-même la conversion. Deux façons :- Si l'on souhaite afficher une chaîne traduite, il est préférable de garder tout côté View, en QML.
- Si l'on souhaite afficher le nom de l'enum tel qu'il est écrit en C++, alors il faut passer par une classe qui sera exposée à QML en tant que singleton (instancié une seule fois par QML), avec une méthode
Q_INVOKABLE
qui convertitMyObject::MyEnum
versQString
.
import My.Namespace 1.0
Text {
property int myEnum: MyObject.MyEnum.Bidule
id: _text
text: myObjectMyEnumToString(myEnum)
function myObjectMyEnumToString(myEnum) {
switch (myEnum) {
case MyObject.MyEnum.Foo:
return qsTr("Foo") // traduction
case MyObject.MyEnum.Bar:
return qsTr("Bar") // traduction
default:
return ""
}
}
}
Déclaration du namespace dans les fichiers .cpp
/.hpp
:
- Macro
Q_NAMESPACE
: déclare le méta-type pour le namespacemy::namespace
. - Macron
Q_ENUM_NS
: déclare les infos nécessaires pour l'enumMyEnum
. - Une fonction statique
init()
qui déclare le namespace à QML.
#pragma once
#include <qobjectdefs.h>
#include <QMetaObject>
#include <QtQml/qqml.h>
namespace my::namespace {
Q_NAMESPACE
enum class MyEnum {
Foo,
Bar,
};
Q_ENUM_NS(MyEnum)
// Implémentation à mettre dans le .cpp.
void init() {
qmlRegisterUncreatableMetaObject(staticMetaObject,
"My.Namespace", // QML import statement
1, // Major version of QML import
0, // Minor version of QML import
"Namespace", // name in QML
"Error: only enums"); // error in case someone tries to create a MyNamespace object
}
}
Dans main.cpp
(ou n'importe où avant la création de l'engine QML) :
my::namespace::init();
import My.Namespace 1.0
Text {
property int myEnum: Namespace.MyEnum.Foo
id: _text
text: myNamespaceMyEnumToString(myEnum)
function myNamespaceMyEnumToString(myEnum) {
switch (myEnum) {
case Namespace.MyEnum.Foo:
return qsTr("Foo") // traduction
case Namespace.MyEnum.Bar:
return qsTr("Bar") // traduction
default:
return ""
}
}
}
Soit une classe A
dans un namespace my::long::namespace
ayant une enum
appelée MyEnum
:
namespace my::first::namespace {
class A : public QObject {
Q_OBJECT
public:
enum class MyEnum {
Foo,
Bar,
};
Q_ENUM(MyEnum)
};
}
Si on désire utiliser cette enum comme Q_PROPERTY
dans une autre classe, il faut mettre le namespace en entier :
namespace my::second::namespace {
class B : public QObject {
Q_OBJECT
Q_PROPERTY(my::first::namespace::MyEnum myEnum READ myEnum WRITE setMyEnum)
};
}