newFunction in QJSEngine missing
-
wrote on 21 Feb 2016, 09:30 last edited by walteste
As QScriptEngine is getting deprecated and will not be there anymore in 5.6, the functionality of (QJSEngine)-newFunction(...) is a must.
Can someone advice if that function will be implemented or another mechanism does exist already?
My goal is to mount native C++ function to the engine.
Thanks in Advance!
-
Hi,
AFAIK, It will not be available as a compiled module but still in sources so you can compile it yourself. That said, you should rather bring your newFunction related question to the interest mailing list. You'll find there Qt's developers/maintainers (this forum is more user oriented)
-
wrote on 22 Feb 2016, 08:04 last edited by
Can you make an example which functionality you want to achieve? I heavily use QML scripting from C++, I could suggest a solution.
-
Can you make an example which functionality you want to achieve? I heavily use QML scripting from C++, I could suggest a solution.
wrote on 22 Feb 2016, 12:55 last edited by@zerocom I am using it to map native c++ functions into the engine to make them available for scripting.
This is the way I amount the native function sqrt into my engine.
QScriptValue func_sqrt = m_engine->newFunction(sqrt, liEngine); m_engine->globalObject().setProperty("sqrt", func_sqrt, QScriptValue::ReadOnly | QScriptValue::Undeletable);
This is an example of the native function:
QScriptValue ScriptModuleMath::sqrt(QScriptContext *context, QScriptEngine *engine, void *arg) { Q_UNUSED(engine) Q_UNUSED(arg) if (context->argumentCount()!=1) { return context->throwError( QScriptContext::SyntaxError, "sqrt(...): illegal number of arguments."); } else if (!context->argument(0).isNumber()) { return context->throwError( QScriptContext::SyntaxError, "sqrt(...): argument 1 is not a number."); } return qSqrt(context->argument(0).toNumber()); }
And this is the way I can use it then in the script:
value = sqrt(4);
-
wrote on 22 Feb 2016, 14:35 last edited by
I guess you want to use QJSEngine::evaluate() right? I think you could create a QJSValue from a QObject which has sqrt() as an invokable function. Set this object as property inside the globalObject from QJSEngine.
class MyExtension : public QObject { Q_OBJECT public: MyExtension(QObject *parent = nullptr) : QObject(parent) {} Q_INVOKABLE double sqrt(double value) { return qSqrt(value); } } QJSEngine engine; engine.globalObject().setProperty("MyMath", engine.newQObject(new MyExtension()));
Inside the script:
MyMath.sqrt(4);
If you run QML scripts, you could also inherit from MyExtension or create a "MyMath" using context property or attachedProperty.
-
I guess you want to use QJSEngine::evaluate() right? I think you could create a QJSValue from a QObject which has sqrt() as an invokable function. Set this object as property inside the globalObject from QJSEngine.
class MyExtension : public QObject { Q_OBJECT public: MyExtension(QObject *parent = nullptr) : QObject(parent) {} Q_INVOKABLE double sqrt(double value) { return qSqrt(value); } } QJSEngine engine; engine.globalObject().setProperty("MyMath", engine.newQObject(new MyExtension()));
Inside the script:
MyMath.sqrt(4);
If you run QML scripts, you could also inherit from MyExtension or create a "MyMath" using context property or attachedProperty.
wrote on 22 Feb 2016, 18:36 last edited by@zerocom Yes, that is almost what I was looking for, but for compatibility reasons I would like to prevent the mentioning of "MyMath.".
Your script:
MyMath.sqrt(4);
The script I would like to have:
sqrt(4);
Is there any way to achieve this?
-
wrote on 23 Feb 2016, 08:50 last edited by
I think it could work like that:
QJSEngine engine; QJSValue myExt = engine.newQObject(new MyExtension()); engine.globalObject().setProperty("sqrt", myExt.property("sqrt"));
I didn't try it, but reading the documentation leads to that solution. You could of cause create a generator function, which adds all methods von MyExtension to the global object.
-
I think it could work like that:
QJSEngine engine; QJSValue myExt = engine.newQObject(new MyExtension()); engine.globalObject().setProperty("sqrt", myExt.property("sqrt"));
I didn't try it, but reading the documentation leads to that solution. You could of cause create a generator function, which adds all methods von MyExtension to the global object.
wrote on 24 Feb 2016, 05:17 last edited by@zerocom said:
I think it could work like that:
QJSEngine engine; QJSValue myExt = engine.newQObject(new MyExtension()); engine.globalObject().setProperty("sqrt", myExt.property("sqrt"));
I didn't try it, but reading the documentation leads to that solution. You could of cause create a generator function, which adds all methods von MyExtension to the global object.
Thanks, this is exactly solving my issue!
-
I think it could work like that:
QJSEngine engine; QJSValue myExt = engine.newQObject(new MyExtension()); engine.globalObject().setProperty("sqrt", myExt.property("sqrt"));
I didn't try it, but reading the documentation leads to that solution. You could of cause create a generator function, which adds all methods von MyExtension to the global object.
wrote on 26 May 2016, 05:01 last edited by@zerocom I had the same issue and your comment helped me to solve it. but this solution seems to be working for predefined number of arguments for invokable functions. is there any way to create an invokable function with variable argument number similar to what we used to do by QScriptContext?