QT — Как получить доступ к C ++ enum из QML?

class StyleClass : public QObject {
public:
typedef enum
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
}  Style;

Style m_style;
//...
};

Файл .h имеет вышеуказанный код. Как получить доступ к перечисленному выше перечислению через QML?

31

Решение

Вы можете обернуть перечисление в класс, который является производным от QObject (и который вы открываете для QML):

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:

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

//...
}
37

Другие решения

По состоянию на Qt 5.8 Вы можете выставить перечисления из namespace:

Определите пространство имен и перечисление:

#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
}

Зарегистрируйте пространство имен (например, в main (), перед созданием Qml View / Context):

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
);

Используйте его в файле QML:

import QtQuick 2.0
import my.namespace 1.0

Item {
Component.onCompleted: console.log(MyNamespace.STYLE_RADIAL)
}

Рекомендации:

https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/

http://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterUncreatableMetaObject

http://doc.qt.io/qt-5/qobject.html#Q_ENUM_NS

17

Дополнительная информация (не документирована до Qt 5.5):

Ваши имена перечислимых значений должен начать с заглавной буквы.

Это будет работать:

enum EnStyle
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
};
Q_ENUMS(EnStyle)

Это не:

enum EnStyle
{
styleRADIAL,
styleENVELOPE,
styleFILLED
};
Q_ENUMS(EnStyle)

Вы не получите никаких ошибок во время компиляции, они просто игнорируются движком QML.

15

Qt также поддерживает определяемые QML типы перечислений начиная с версии 5.10 Qt. В качестве альтернативы ответу air-dex на основе C ++ теперь вы также можете использовать QML для создания типов перечислений:

Style.qml:

import QtQuick 2.0

QtObject {
enum EnStyle {
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
}
}

Если вы собираетесь использовать только перечисления в своем коде QML, это решение намного проще. Вы можете получить доступ к перечисленному выше перечислению с типом Style в qml, например:

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")
}
}

Увидеть Вот для другого примера использования перечисляемого типа на основе QML.

5

Сделать moc известно о вашем перечислении с помощью Q_ENUMS макрос, как описано в документы. Вы должны зарегистрировать класс, который «владеет» перечислением до он используется, как описано в документы.

Блок цитаты Ашифа действителен, только если перечисление является глобальным или принадлежит неQObject производный класс.

3

Все эти решения не могут быть использованы, используя этот enum-класс в качестве параметра для сигнала / слота. Этот код компилируется, но не работает в QML:

class DataEmitter : public QObject
{
Q_OBJECT

public:
...
signals:
void setStyle(StyleClass::EnStyle style);
}

...

emit setStyle(StyleClass.STYLE_RADIAL);

QML-часть:

Connections {
target: dataEmitter
onSetStyle: {
myObject.style=style
}
}

И этот код генерирует ошибку во время выполнения, как это:

IndicatorArea.qml:124: Error: Cannot assign [undefined] to int

Чтобы этот код работал, вы должны иметь дополнительный тип метаобъекта реестра Qt:

qRegisterMetaType<StyleClass::EnStyle>("StyleClass.EnStyle");

Более подробно написано здесь: https://webhamster.ru/mytetrashare/index/mtb0/1535044840rbtgvfmjys (Рус)

0
По вопросам рекламы [email protected]