6

I try to expose an object as a global property to Java Script which has the method below:

Q_INVOKABLE MyObject* createMyObject();

MyObject is derived from QObject.

when I call this method in Java Script it returns an object of type:

QVariant(MyObject*)

I'm wondering if it's possible to automatically convert it to QJSValue so I can use it further in the script?

4 Answers 4

4

Seems that Java Script uses QVariant as an opaque wrapper around any 'unknown' type. The value can be passed around easily but non of its properties can be used and non of its methods can be invoked. To be used in script it should be converted to QJSValue. The only way I found is declaring helper function like this:

Q_INVOKABLE QJSValue convert(QVariant var)
{
    return _engine.newQObject(var.value<QObject*>());
}

then it's possible to convert QVariant to QJSValue:

var obj = convert(createMyObject());

and obj will be of type

MyObject

So now it can be used in script.

Sign up to request clarification or add additional context in comments.

2 Comments

Good solution. Will note it :) .
After a while more correct solution was found (using qmlRegisterType). See my recent answer.
3

All that needs to be done is calling the method below somewhere before referencing MyObject in the script.

qmlRegisterType<MyObject>("", 1, 0, "MyObject");

Then createMyObject method will return correct type without any conversion:

var obj = createMyObject();

MyObject

Actually if we change type of the method below

Q_INVOKABLE MyObject* createMyObject();

to

Q_INVOKABLE QObject* createMyObject();

it will start working even without

qmlRegisterType

1 Comment

Surprisingly it does! I don't use qml, and it works with qmlRegisterType and doesn't with qRegisterMetaType.
2

You can use QJSEngine::newQObject() method.

Use newQObject() to wrap a QObject (or subclass) pointer. newQObject() returns a proxy script object; properties, children, and signals and slots of the QObject are available as properties of the proxy object. No binding code is needed because it is done dynamically using the Qt meta object system.

Please read further details at QJSEngine Class: QObject Integration.

1 Comment

Yes, I know. But it requires wrapper around every Q_INVOKABLE in my class to convert return value into QJSValue.
0

I am in a similar situation, trying to use QJSEngine for scripting (at the moment stuck at trying to expose a QList to QJSEngine...)

I think the easiest way to expose an existing C++ object to scripting is like so:

//create c++ file object
MyObject* anObject = new MyObject();

//make c++ object available to script
QJSValue scriptObject = myEngine.newQObject(anObject);
myEngine.globalObject().setProperty("obj", scriptObject);

You should now be able to access "obj" from script.

By the way, how to you find out the type in script (QVariant(MyObject*))?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.