MyTetra Share
Делитесь знаниями!
Как создать перечисление enum, которое будет работать и в C++ и в QML
Время создания: 23.08.2018 20:20
Текстовые метки: qt, qml, перечисление, enum, c++, сигнал, слот, параметр, тип
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - QML - Краткая памятка по QML
Запись: xintrea/mytetra_syncro/master/base/15350448405jdnjmh6s7/text.html на raw.github.com

Часто возникает необходимость сделать такое перечисление enum, которое будет находиться в C++, и будет проброшено в QML. Кроме того, необходимо, чтобы тип данного перечисления мог быть использован в параметрах сигналов и слотов.


Вот как это делается.


Вначале регистрируется класс с перечислением enum, который, в принципе, состоит из одного только заголовка, то есть реализация ему не нужна:



Файл DataQuality.h


#ifndef DATAQUALITY_H

#define DATAQUALITY_H


#include <QObject>


class DataQuality

{

Q_GADGET // Вместо крупного QObject добавляется только рефлексия, которая используется в QML


public:


enum Value {

None=0,

Normal=1,

Imperfect=2

};

Q_ENUM(Value)


};


#endif // DATAQUALITY_H



Данный класс необходимо зарегистрировать в QML-пространстве вот таким способом:



qmlRegisterUncreatableType<DataQuality>("company.DataQuality", 1, 0,

"DataQuality",

"You can't create an instance of the DataQuality.");

qRegisterMetaType<DataQuality::Value>("DataQuality.Value");



В первой строке регистрируется тип для QML. Второй строкой регистрируется тип для метаобъектной системы Qt, чтобы данный тип можно было использовать в качестве параметров в сигналах и слотах. Особенность такой регистрации в том, что для доступа к значениям перечисления используется сокращенный синтаксис. То есть, вместо:



C++: DataQuality::Value::Normal

QML: DataQuality.Value.Normal



Можно писать так:



C++: DataQuality::Normal

QML: DataQuality.Normal



Чтобы пользоваться данным перечислением в QML-части, необходимо не забыть сделать импорт:



import company.DataQuality 1.0



Для использования данного перечисления в C++ коде необходимо, естественно, не забыть сделать подключение заголовка #include DataQuality.h.


Данное перечисление можно использовать как тип. Вот пример возвращения из функции:



DataQuality::Value getNormalQuality()

{

return DataQuality::Normal;

}



И можно использовать в качестве параметров в сигналах и слотах. Код на C++ выглядит так:



class ViewDataEmitter : public QObject

{

Q_OBJECT


public:

...

signals:

void setAngle(float angle, DataQuality::Value quality);

}


...


emit setAngle(0.5, DataQuality::Normal);



А QML-часть выглядит так:



Connections {

target: viewDataEmitter

onSetAngle: {

arrow.angle=angle

arrow.quality=quality;

}

}



Понятно, что перечисление enum обычно размещают не в рамках отдельного класса, а в рамках того класса, где оно используется. Но при работе с QML доступ к перечислению не так тривиален как в чистом C++ коде. Поэтому здесь описан "не совсем идеологически правильный" способ использования перечисления. Главное здесь то, что он работает.



Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования