I am writing scripting wrappers for my SW so I can control my SW via scripts. The purpose of the wrapper classes is to separate the scripting interface from the actual class because I might not want to expose all of the signals and slots of the class. I'm using Qt 5.13 and QJSEngine.
My issue is that based on what I've read and what I've experimented it seems that to be able to expose an enum it needs to be within a class that inherits QObject and is exposed via newQObject()/setProperty(). However I do not want to expose the class Foo in the following example, but I still want to expose the enum Foo::Bar to the scripting environment. How do I do this? Q_ENUM seems to assume the enum is within a QObject and that the QObject is exposed (property) in the scripting environment. Here is a short example what I am doing (I want to be able to call FooWrapper::slot1() from the scripting environment):
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;
};
Well this is clearly very late for Dago, the OP (sorry!). In case anyone else runs into this...
One option is same as for QML in general, which is that one can register enums and flags from a namespace. Using
Q_ENUM_NS()andQ_FLAG_NS()(for flags theQ_DECLARE_FLAGS()call stays the same, alsoQ_DECLARE_OPERATORS_FOR_FLAGS()outside the namespace, same as with a class, if you want those).There is my related answer here: How to access C++ enum from QML?
But for pure
JSEngineusage it is enough to just set the namespace'sQMetaObjectas a property in the engine... no need forqmlRegisterUncreatableMetaObject...stuff.So to sum up...
Later in the
QJSEngineinitialization routine somewhere...Then in the JS environment the enum is available as a property of the namespace itself.
or in a script...
Another option may be to keep the enums in the class and register the class'
QMetaObjectas a property of the engine... just do not mark the constructor (or any other static methods) asQ_INVOKABLE.HTH,
-Max
References:
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
I cannot find a direct reference to registering namespace meta objects as I just described... I assure you it works (and has for quite a few versions).
A vague reference to it here, at the end of the section.. https://doc.qt.io/qt-5/qqmlengine.html#QML_ELEMENT
Another even less relevant (but possibly interesting): https://doc.qt.io/qt-6/qqmlengine.html#QML_EXTENDED_NAMESPACE