Unfreezing the QQmlEngine for script evaluation before GUI loading



  • In Qt 4.7 the QML Engine ran ontop of the QScriptEngine and had a special scriptClass which forced it into read-only mode after creation. If you removed the scriptClass you could get write-access temporarily to the engine and load a bunch of custom utility methods (or objects) which would remain global to all QML objects.

    The method of hijacking the internal engine (which was private) is described here: "Importing an existing QScriptExtensionPlugin to QML":http://qt-project.org/forums/viewreply/28180/ however this no longer applies because the Qt 5 version uses QJSEngine underneath and no longer has a scriptClass concept.

    If you jump into the internals it uses the EMCA script freeze object on the global object which locks it entirely unless you recreate it which looks to be a long backwards and unreliable process.

    Is there any way to unfreeze / prevent this mechanism temporarily so that one can inject custom definitions into the global object before it gets locked away? I know by design the Qt devs locked the global object so one can't accidentally modify it but having no way to intentionally modify it from the C++ side prior to the lock is most annoying. If you use a standalone QJSEngine then you no longer have this problem.

    All I'm really trying to do is:
    @
    QQmlEngine e;
    e.evaluate("var Utils = Object; Utils.myMethod = function(){};");

    //Give the engine to the QQmlViewer
    QQmlViewer view(e);
    view.setSource("GUI.qml");
    view.show();
    //at this point my QUI.qml javascript sections can reference the Utils class
    @



  • I think you can use something like this:

    (I'm using this to load some QML model before the actual GUI loading, JSCode would be the same, I think.)

    @
    QQmlEngine e;
    QQmlComponent global_object_component(&e, QUrl::fromLocalFile("global_object.qml"), QmlComponent::PreferSynchronous);
    QObject *global_object = global_object_component.create();
    if (global_object)
    {
    e.rootContext()->setContextProperty("global_object", global_object);

    QQmlViewer view(e);
    view.setSource("GUI.qml");
    view.show();
    //at this point my QUI.qml can reference global_object
    }
    else
    {
    //error
    }
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.