我正在为我的软件编写脚本 Package 器,这样我就可以通过脚本控制我的软件。 Package 器类的目的是将脚本接口与实际类分开,因为我可能不想暴露类的所有信号和插槽。我使用Qt 5.13和QJSEngine。
我的问题是,基于我所读到的和我所做的,似乎要能够暴露一个枚举,它需要在一个继承QObject的类中,并通过newQObject()/setProperty()暴露。然而,我不想在下面的例子中暴露类Foo,但我仍然想向脚本环境暴露枚举Foo::Bar。我该怎么做呢?Q_ENUM似乎假设枚举在一个QObject中,QObject在脚本环境中暴露(属性)。下面是一个简短的例子(我想能够从脚本环境调用FooWrapper::slot 1()):
class Foo : public QObject
{
Q_OBJECT
public:
Foo(QJSEngine& engine)
{
auto wrapper = new FooWrapper(this, engine);
}
enum class Bar
{
VAL1,
VAL2
};
public slots:
void slot1(Bar bar);
void slot2();
};
class FooWrapper : public QObject
{
Q_OBJECT
public:
Foo(Foo& foo, QJSEngine& engine)
: foo(&foo)
{
QJSValue obj = engine.newQObject(this);
auto gObj = engine.globalObject();
gObj.setProperty("foo", obj);
}
public slots:
void slot1(Bar bar)
{
foo->slot1(bar);
}
private:
Foo* foo;
};
1条答案
按热度按时间hgncfbus1#
好吧,这对达戈来说显然已经很晚了,OP(抱歉!)。万一还有人碰到这个...
其中一个选项与QML相同,就是可以从命名空间注册枚举和标志。使用
Q_ENUM_NS()
和Q_FLAG_NS()
(对于标志,Q_DECLARE_FLAGS()
调用保持不变,命名空间外的Q_DECLARE_OPERATORS_FOR_FLAGS()
调用也保持不变,与类的调用相同,如果需要的话)。这里有我的相关回答:如何从QML访问C++枚举?
但是对于纯粹的
JSEngine
用法,只需将名称空间的QMetaObject
设置为引擎中的属性就足够了...不需要qmlRegisterUncreatableMetaObject...
之类的东西。所以总结一下...
稍后在
QJSEngine
初始化例程的某个地方...然后在JS环境中,枚举可以作为名称空间本身的属性使用。
或者在剧本里...
另一个选项可能是保留类中的枚举,并将类的
QMetaObject
注册为引擎的属性...只是不要将构造函数(或任何其他静态方法)标记为Q_INVOKABLE
。嘿,
参考文献:
https://doc.qt.io/qt-6/qjsengine.html#newQMetaObject
https://doc.qt.io/qt-6/qobject.html#Q_NAMESPACE
https://doc.qt.io/qt-6/qobject.html#Q_ENUM_NS
我 * 不能 * 找到一个直接引用注册名称空间 meta对象,就像我刚刚描述的那样...我向你保证它是有效的(并且已经在相当多的版本中)。
在这一节的结尾,有一个模糊的参考。https://doc.qt.io/qt-5/qqmlengine.html#QML_ELEMENT
另一个甚至不太相关(但可能有趣):https://doc.qt.io/qt-6/qqmlengine.html#QML_EXTENDED_NAMESPACE