class StyleClass : public QObject {
public:
typedef enum
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
} Style;
Style m_style;
//...
};
Die .h-Datei enthält den obigen Code. Wie kann über QML auf das oben genannte Enum zugegriffen werden?
Sie können das Enum in eine Klasse einschließen, die von QObject abgeleitet ist (und die Sie für QML freigeben)
style.hpp:
#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.cpp:
#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
//...
}
Ab Qt 5.8 können Sie Enummen von einer namespace
aus anzeigen:
Definieren Sie den Namespace und die Enumeration:
#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
}
Registrieren Sie den Namespace (z. B. in main (), bevor Sie eine Qml-Ansicht/einen Kontext erstellen):
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
);
Verwenden Sie es in einer QML-Datei:
import QtQuick 2.0
import my.namespace 1.0
Item {
Component.onCompleted: console.log(MyNamespace.STYLE_RADIAL)
}
Verweise:
https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/
http://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterUncreatableMetaObject
Zusätzliche Informationen (nicht vor Qt 5.5 dokumentiert):
Ihre Aufzählungsnamen müssen mit einem Großbuchstaben beginnen.
Das wird funktionieren:
enum EnStyle
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
};
Q_ENUMS(EnStyle)
Das tut nicht:
enum EnStyle
{
styleRADIAL,
styleENVELOPE,
styleFILLED
};
Q_ENUMS(EnStyle)
Beim Kompilieren werden keine Fehler angezeigt, sie werden von der QML-Engine einfach ignoriert.
Qt unterstützt auch QML-definierte Aufzählungstypen seit Qt-Version 5.10. Als Alternative zur C++ - basierten Antwort von air-dex können Sie QML jetzt auch verwenden, um Aufzählungstypen zu erstellen:
Style.qml:
import QtQuick 2.0
QtObject {
enum EnStyle {
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
}
}
Wenn Sie nur die Aufzählungen in Ihrem QML-Code verwenden möchten, ist diese Lösung wesentlich einfacher. Sie können auf das oben genannte Enum mit dem Style-Typ in qml zugreifen, zum Beispiel:
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")
}
}
Unter here finden Sie ein weiteres Verwendungsbeispiel für einen QML-basierten Aufzählungstyp.
Machen Sie das moc
mit Hilfe des Makros Q_ENUMS
auf Ihr Enum aufmerksam, wie in docs beschrieben. Sie müssen die Klasse registrieren, die das Enum besitzt, bevor verwendet wird, wie in docs beschrieben.
Der Anführungsblock von Ashif ist nur gültig, wenn das Enum global ist oder einer nicht -QObject
abgeleiteten Klasse gehört.
Alle diese Lösungen können nicht aktiviert werden. Diese Enum-Klasse wurde als Parameter für Signal/Slot verwendet. Dieser Code wird kompiliert, funktioniert aber nicht in QML:
class DataEmitter : public QObject
{
Q_OBJECT
public:
...
signals:
void setStyle(StyleClass::EnStyle style);
}
...
emit setStyle(StyleClass.STYLE_RADIAL);
QML-Teil:
Connections {
target: dataEmitter
onSetStyle: {
myObject.style=style
}
}
Und dieser Code generiert Laufzeitfehler wie folgt:
IndicatorArea.qml:124: Error: Cannot assign [undefined] to int
Damit dieser Code funktioniert, müssen Sie einen zusätzlichen Registrierungs-Qt-Metaobjekttyp hinzufügen:
qRegisterMetaType<StyleClass::EnStyle>("StyleClass.EnStyle");
Weitere Details hier geschrieben: https://webhamster.ru/mytetrashare/index/mtb0/1535044840rbtgvfmjys (rus)
Ich habe eine sehr gute Lösung für die Verwendung von ENUMs aus der C++ - Klasse in QML gefunden, hier: Aufzählungen in Qt QML - qml.guide . Der Beitrag war so gut, dass ich mich verpflichtet fühlte, ihn hier mit der SO) Community zu teilen. Und IMHO-Zuschreibung sollte immer erfolgen, daher der Link zum Beitrag hinzugefügt.
Der Beitrag beschreibt im Wesentlichen:
1) So erstellen Sie einen ENUM-Typ in Qt/C++:
// statusclass.h
#include <QObject>
class StatusClass
{
Q_GADGET
public:
explicit StatusClass();
enum Value {
Null,
Ready,
Loading,
Error
};
Q_ENUM(Value)
};
2) So registrieren Sie die Klasse bei der QML-Engine als "Uncreatable Type":
(Dies ist der Teil, der diese Lösung schön und deutlich macht.)
// main.cpp
...
QQmlApplicationEngine engine;
qmlRegisterUncreatableType<StatusClass>("qml.guide", 1, 0, "StatusClass",
"Not creatable as it is an enum type.");
...
Die Verwendung von qmlRegisterUncreatableType
verhindert die Instanziierung von StatusClass
in QML. Eine Warnung wird protokolliert, wenn ein Benutzer versucht, diese Klasse zu instanziieren:
qrc:/main.qml:16 Not creatable as it is an enum type.
3) Zum Schluss, wie man ENUM in einer QML-Datei benutzt:
// main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import qml.guide 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Component.onCompleted: {
console.log(StatusClass.Ready); // <--- Here's how to use the ENUM.
}
}
Wichtiger Hinweis:
ENUM soll verwendet werden, indem es mit dem Klassennamen wie diesem referenziert wird. StatusClass.Ready
. Wenn dieselbe Klasse auch in QML als Kontexteigenschaft verwendet wird ...
// main.cpp
...
QQmlApplicationEngine engine;
qmlRegisterUncreatableType<StatusClass>("qml.guide", 1, 0, "StatusClass",
"Not creatable as it is an enum type.");
StatusClass statusClassObj; // Named such (perhaps poorly) for the sake of clarity in the example.
engine.rootContext()->setContextProperty("statusClassObj", &statusClassObj); // <--- like this
...
... dann wird manchmal versehentlich ENUM mit der Eigenschaft context anstelle des Klassennamens verwendet.
// main.qml
...
Component.onCompleted: {
// Correct
console.log(StatusClass.Ready); // 1
// Wrong
console.log(statusClassObj.Ready); // undefined
}
...
Der Grund, warum Leute dazu neigen, diesen Fehler zu machen, liegt darin, dass das Autocomplete-Feature von Qt Creator ENUM als Option auflistet, sowohl bei der Referenzierung unter Verwendung des Klassennamens als auch der Kontexteigenschaft . Seien Sie also vorsichtig, wenn Sie sich in einer solchen Situation befinden.