class StyleClass : public QObject {
public:
typedef enum
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
} Style;
Style m_style;
//...
};
.hファイルには上記のコードが含まれています。 QMLを介して上記の列挙型にアクセスする方法
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
//...
}
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ビュー/コンテキストを作成する前に):
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
追加情報( Qt 5.5 より前に文書化されていません):
列挙値名mustは大文字で始まる必要があります。
これは動作します:
enum EnStyle
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
};
Q_ENUMS(EnStyle)
これはしません:
enum EnStyle
{
styleRADIAL,
styleENVELOPE,
styleFILLED
};
Q_ENUMS(EnStyle)
コンパイル時にエラーは発生しません。エラーはQMLエンジンによって無視されます。
Qtは、Qtバージョン5.10以降のQML定義の列挙型もサポートしています。 air-dexによるC++ベースの回答の代替として、QMLを使用して列挙型を作成することもできます。
Style.qml:
import QtQuick 2.0
QtObject {
enum EnStyle {
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
}
}
QMLコードで列挙型のみを使用する場合、このソリューションははるかに簡単です。次に、qmlのStyleタイプを使用して上記の列挙型にアクセスできます。次に例を示します。
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ベースの列挙型の別の使用例については、 here を参照してください。
このすべてのソリューションは、この列挙型クラスを信号/スロットのパラメーターとして使用して有効にすることはできません。このコードはコンパイルされますが、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 (rus)
ここで、QMLのC++クラスのENUMを使用するための非常に素晴らしいソリューションを見つけました。 Qt QMLの列挙-qml.guide 。投稿はとても良かったので、ここでSOコミュニティと共有する義務がありました。IMHOの帰属は常に行われるべきであるため、投稿へのリンクを追加しました。
投稿では基本的に次のことを説明しています。
1)Qt/C++でENUM型を作成する方法:
// statusclass.h
#include <QObject>
class StatusClass
{
Q_GADGET
public:
explicit StatusClass();
enum Value {
Null,
Ready,
Loading,
Error
};
Q_ENUM(Value)
};
2)クラスを「作成できないタイプ」としてQMLエンジンに登録する方法:
(これは、このソリューションを素敵で際立たせる部分です。)
// main.cpp
...
QQmlApplicationEngine engine;
qmlRegisterUncreatableType<StatusClass>("qml.guide", 1, 0, "StatusClass",
"Not creatable as it is an enum type.");
...
qmlRegisterUncreatableType
を使用すると、QMLでStatusClass
がインスタンス化されなくなります。ユーザーがこのクラスをインスタンス化しようとすると、警告が記録されます。
qrc:/main.qml:16 Not creatable as it is an enum type.
3)最後に、QMLファイルでENUMを使用する方法:
// 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.
}
}
重要なメモ:
ENUMは、次のようにクラス名で参照することで使用されることになっていますStatusClass.Ready
。同じクラスがコンテキストプロパティとしてQMLでも使用されている場合...
// 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
...
...その後、クラス名の代わりにコンテキストプロパティでENUMを誤って使用することがあります。
// main.qml
...
Component.onCompleted: {
// Correct
console.log(StatusClass.Ready); // 1
// Wrong
console.log(statusClassObj.Ready); // undefined
}
...
人々がこの間違いを犯しがちな理由は、Qt Creatorのオートコンプリート機能は、クラス名とコンテキストプロパティを使用して参照するときの両方でENUMをオプションとしてリストするであるためです。したがって、そのような状況では注意してください。