Comment accéder à C++ enum à partir de QML?
class StyleClass : public QObject {
public:
typedef enum
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
} Style;
Style m_style;
//...
};
L' .le fichier h a le code ci-dessus. comment accéder à l'enum ci-dessus par QML?
6 réponses
vous pouvez envelopper l'enum dans une classe qui dérive de QObject (et que vous exposez à QML):
style.php :
#ifndef STYLE_HPP
#define STYLE_HPP
#include <QtGlobal>
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
// Qt 4
#include <QDeclarativeEngine>
#else
// Qt 5
#include <QQmlEngine>
#endif
// Required derivation from QObject
class StyleClass : public QObject
{
Q_OBJECT
public:
// Default constructor, required for classes you expose to QML.
StyleClass() : QObject() {}
enum EnStyle
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
};
Q_ENUMS(EnStyle)
// Do not forget to declare your class to the QML system.
static void declareQML() {
qmlRegisterType<StyleClass>("MyQMLEnums", 13, 37, "Style");
}
};
#endif // STYLE_HPP
main.rpc:
#include <QApplication>
#include "style.hpp"
int main (int argc, char ** argv) {
QApplication a(argc, argv);
//...
StyleClass::declareQML();
//...
return a.exec();
}
QML Code:
import MyQMLEnums 13.37
import QtQuick 2.0 // Or 1.1 depending on your Qt version
Item {
id: myitem
//...
property int item_style: Style.STYLE_RADIAL
//...
}
information additionnelle (non documentée avant Qt 5.5):
les noms de vos valeurs enum commencer par une lettre majuscule.
Cela fonctionne:
enum EnStyle
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
};
Q_ENUMS(EnStyle)
Cela ne fonctionne pas:
enum EnStyle
{
styleRADIAL,
styleENVELOPE,
styleFILLED
};
Q_ENUMS(EnStyle)
vous n'obtiendrez aucun type d'erreur au moment de la compilation, ils sont simplement ignorés par le moteur QML.
à partir de Qt 5.8 vous pouvez exposer les énumérations à partir d'un namespace
:
Définir l'espace de noms enum:
#include <QObject>
namespace MyNamespace
{
Q_NAMESPACE // required for meta object creation
enum EnStyle {
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
};
Q_ENUM_NS(EnStyle) // register the enum in meta object data
}
enregistrer l'espace de noms(ex. dans main(), avant de créer un Qml Vue/Contexte):
qmlRegisterUncreatableMetaObject(
MyNamespace::staticMetaObject, // static meta object
"my.namespace", // import statement (can be any string)
1, 0, // major and minor version of the import
"MyNamespace", // name in QML (does not have to match C++ name)
"Error: only enums" // error in case someone tries to create a MyNamespace object
);
L'utiliser dans un QML fichier:
import QtQuick 2.0
import my.namespace 1.0
Item {
Component.onCompleted: console.log(MyNamespace.STYLE_RADIAL)
}
Références:
https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/
http://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterUncreatableMetaObject
Qt prend également en charge les types d'enum définis par QML depuis la version 5.10 de Qt. Comme alternative à la réponse basée sur C++par air-dex, vous pouvez maintenant aussi utiliser QML pour créer des types enum:
Style.qml:
import QtQuick 2.0
QtObject {
enum EnStyle {
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
}
}
si vous avez seulement l'intention d'utiliser les enum dans votre code QML, cette solution est beaucoup plus simple. Vous pouvez accéder à l'enum ci-dessus avec le type de Style dans qml puis, par exemple:
import VPlayApps 1.0
import QtQuick 2.9
App {
property int enStyle: Style.EnStyle.STYLE_RADIAL
Component.onCompleted: {
if(enStyle === Style.EnStyle.STYLE_ENVELOPE)
console.log("ENVELOPE")
else
console.log("NOT ENVELOPE")
}
}
Voir ici pour un autre exemple d'utilisation d'un Type enum basé sur QML.
moc
conscient de votre enum Q_ENUMS
macro, comme décrit dans la docs. Vous devez enregistrer la classe qui possède l'enum avant il est utilisé, comme décrit dans la docs.
le bloc de devis D'Ashif n'est valide que si l'enum est un global ou appartient à un non-QObject
classe dérivée.
toutes ces solutions ne peuvent pas être activées utilisé cette classe d'enum comme paramètre pour signal / slot. Ce code compilera, mais ne fonctionnera pas dans QML:
class DataEmitter : public QObject
{
Q_OBJECT
public:
...
signals:
void setStyle(StyleClass::EnStyle style);
}
...
emit setStyle(StyleClass.STYLE_RADIAL);
QML-part:
Connections {
target: dataEmitter
onSetStyle: {
myObject.style=style
}
}
Et ce code générer d'erreur à l'exécution, comme ceci:
IndicatorArea.qml:124: Error: Cannot assign [undefined] to int
Pour que ce code fonctionne, vous devez registre supplémentaires Qt metaobject type:
qRegisterMetaType<StyleClass::EnStyle>("StyleClass.EnStyle");
Plus de détails ici: https://webhamster.ru/mytetrashare/index/mtb0/1535044840rbtgvfmjys (rus)