Aqu*_*irl 36 c++ qt qml qtquick2
class StyleClass : public QObject {
public:
typedef enum
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
} Style;
Style m_style;
//...
};
Run Code Online (Sandbox Code Playgroud)
.h文件包含上面的代码.如何通过QML访问上面的枚举?
air*_*dex 41
您可以将枚举包装在一个派生自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
Run Code Online (Sandbox Code Playgroud)
main.cpp中:
#include <QApplication>
#include "style.hpp"
int main (int argc, char ** argv) {
QApplication a(argc, argv);
//...
StyleClass::declareQML();
//...
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
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
//...
}
Run Code Online (Sandbox Code Playgroud)
Max*_*rno 22
从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
}
Run Code Online (Sandbox Code Playgroud)
在创建Qml View/Context之前注册命名空间(例如,在main()中):
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
);
Run Code Online (Sandbox Code Playgroud)
在QML文件中使用它:
import QtQuick 2.0
import my.namespace 1.0
Item {
Component.onCompleted: console.log(MyNamespace.STYLE_RADIAL)
}
Run Code Online (Sandbox Code Playgroud)
参考文献:
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
Ric*_*832 20
其他信息(在Qt 5.5之前未记录):
您的枚举值名称必须以大写字母开头.
这将有效:
enum EnStyle
{
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
};
Q_ENUMS(EnStyle)
Run Code Online (Sandbox Code Playgroud)
这不是:
enum EnStyle
{
styleRADIAL,
styleENVELOPE,
styleFILLED
};
Q_ENUMS(EnStyle)
Run Code Online (Sandbox Code Playgroud)
你不会在编译时遇到任何错误,它们会被QML引擎忽略.
zeF*_*ree 10
我找到了一个非常好的解决方案,用于在 QML 中使用来自 C++ 类的 ENUM,这里: Enums in Qt QML - qml.guide。这篇文章太好了,我觉得有必要在这里与 SO 社区分享。恕我直言,应该始终进行归因,因此添加了帖子的链接。
该帖子主要描述了:
1) 如何在 Qt/C++ 中创建 ENUM 类型:
// statusclass.h
#include <QObject>
class StatusClass
{
Q_GADGET
public:
explicit StatusClass();
enum Value {
Null,
Ready,
Loading,
Error
};
Q_ENUM(Value)
};
Run Code Online (Sandbox Code Playgroud)
2)如何使用 QML 引擎将类注册为“不可创建的类型”:(
这是使该解决方案美观而独特的部分。)
// main.cpp
...
QQmlApplicationEngine engine;
qmlRegisterUncreatableType<StatusClass>("qml.guide", 1, 0, "StatusClass",
"Not creatable as it is an enum type.");
...
Run Code Online (Sandbox Code Playgroud)
使用qmlRegisterUncreatableType
防止StatusClass
在 QML 中的实例化。如果用户尝试实例化此类,则会记录警告:
qrc:/main.qml:16 Not creatable as it is an enum type.
Run Code Online (Sandbox Code Playgroud)
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.
}
}
Run Code Online (Sandbox Code Playgroud)
重要说明:
应该通过使用类名引用它来使用 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
...
Run Code Online (Sandbox Code Playgroud)
...然后,有时人们会不小心将 ENUM 与上下文属性而不是类名一起使用。
// main.qml
...
Component.onCompleted: {
// Correct
console.log(StatusClass.Ready); // 1
// Wrong
console.log(statusClassObj.Ready); // undefined
}
...
Run Code Online (Sandbox Code Playgroud)
人们倾向于犯这个错误的原因是因为Qt Creator 的自动完成功能将 ENUM 作为选项列出,无论是在使用类名还是上下文属性进行引用时。因此,在这种情况下,请谨慎行事。
自Qt版本5.10起,Qt还支持QML定义的枚举类型.作为air-dex基于C++的回答的替代方法,您现在还可以使用QML创建枚举类型:
Style.qml:
import QtQuick 2.0
QtObject {
enum EnStyle {
STYLE_RADIAL,
STYLE_ENVELOPE,
STYLE_FILLED
}
}
Run Code Online (Sandbox Code Playgroud)
如果您只打算在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")
}
}
Run Code Online (Sandbox Code Playgroud)
有关基于QML的枚举类型的另一个用法示例,请参见此处.
无法启用所有这些解决方案,使用此枚举类作为信号/插槽的参数。这段代码可以编译,但在 QML 中不起作用:
class DataEmitter : public QObject
{
Q_OBJECT
public:
...
signals:
void setStyle(StyleClass::EnStyle style);
}
...
emit setStyle(StyleClass.STYLE_RADIAL);
Run Code Online (Sandbox Code Playgroud)
QML-部分:
Connections {
target: dataEmitter
onSetStyle: {
myObject.style=style
}
}
Run Code Online (Sandbox Code Playgroud)
此代码生成运行时错误,如下所示:
IndicatorArea.qml:124: Error: Cannot assign [undefined] to int
Run Code Online (Sandbox Code Playgroud)
对于此代码工作,您必须附加注册表 Qt 元对象类型:
qRegisterMetaType<StyleClass::EnStyle>("StyleClass.EnStyle");
Run Code Online (Sandbox Code Playgroud)
更多细节写在这里:https ://webhamster.ru/mytetrashare/index/mtb0/1535044840rbtgvfmjys(俄罗斯)
归档时间: |
|
查看次数: |
36079 次 |
最近记录: |