[Interest] How to set a QJSValue with functions as a context property in QQmlContext?
Richard Weickelt
richard at weickelt.de
Mon Apr 13 16:58:25 CEST 2020
Is there a way to set a QJSValue as a context property in QQmlContext and
retain function properties?
I am loading a .js file with QJSEngine::importModule(). The result is
QJSValue object containing all exported functions and properties from the
module.
// file.js
export function someFunction(someArg) {
return someArg;
}
export someVar = "value";
// importing code
QJSValue module = engine->importModule("/path/to/file.js");
Now I want to evaluate JS code snippets with my modules installed. I need
fine-grained control over contexts and my real-world application uses a
context hierarchy. So I use QQmlExpression and set my imported module as a
context property:
fileContext->setContextProperty("Test", importedObject.toVariant());
QQmlExpression expression(fileContext,
nullptr,
"Test.someFunction(\"value\");");
QVariant value = expression.evaluate(nullptr);
qDebug() << value;
But the result is an invalid QVariant. I guess that the conversion from
QJSValue to QVariant cannot retain callable properties. It works when
referencing Test.someVar in above expression.
So is there a way to use a QJSValue object with functions as a context property?
Thanks
Here is the complete test project
---------------------------------
#include <QCoreApplication>
#include <QDebug>
#include <QTimer>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlExpression>
void test() {
QQmlEngine *engine = new QQmlEngine(QCoreApplication::instance());
QQmlContext *fileContext = new QQmlContext(engine->rootContext());
QJSValue importedObject = engine->importModule("/path/to/file.js");
fileContext->setContextProperty("Test", importedObject.toVariant());
QQmlExpression expression(fileContext,
nullptr,
"Test.someFunction(\"value\");");
QVariant value = expression.evaluate(nullptr);
qDebug() << value;
QCoreApplication::quit();
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QTimer::singleShot(0, &app, &test);
return app.exec();
}
More information about the Interest
mailing list