1

I have a QML file that imports a JavaScript library:

import "qrc:/scripts/protobuf.js" as PB

This library modifies the 'global' object during setup. Simplified, the JS library is:

.pragma library
(function(global){
  global.dcodeIO = global.dcodeIO || {};
  global.dcodeIO.ProtoBuf = {}; // In reality, a complex object
})(this);

On Windows and Linux this works as expected; later in my QML file I write var ProtoBuf = PB.dcodeIO.ProtoBuf; and it finds the dcodeIO property added to the 'global' object and properly gives me the object I need.

However, on another platform, the same code does not work. I get an error that it cannot read property ProtoBuf of undefined. I add debugging lines to my QML and see:

console.log(PB.dcodeIO);                //-> undefined
for (var k in PB) console.log(k,PB[k]); //-> (no enumerable properties logged)

Yet, the JavaScript code in the library is loaded and runs. Within the library if I add console.log(global.dcodeIO) after the line linked above I see [object Object].

What might the difference be? How can I determine why Qt is running my JavaScript file, but not successfully associating the global object with PB?

3
  • On which platform does it not work? Commented Aug 5, 2016 at 11:20
  • @Mitch It's NVIDIA V4L (Vibrante 4 Linux) running on an NVIDIA PX2. FWIW I'm now debugging the problem with the Qt developers, with no answer yet. Commented Aug 5, 2016 at 13:50
  • same problem on Qt 5.9 Commented Jun 1, 2017 at 11:32

2 Answers 2

1

The points listed under JavaScript Environment Restrictions could be relevant here:

JavaScript code cannot modify the global object.

In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created.

...

Any attempt to modify the global object - either implicitly or explicitly - will cause an exception. If uncaught, this will result in an warning being printed, that includes the file and line number of the offending code.

Although you said it's working on two platforms, just not a third, so perhaps your usage is correct and it's a bug.

There's also this point:

Global code is run in a reduced scope.

Though that point seems to be about accessing QML objects from the loaded script.

The documentation has always been unclear to me on this subject. http://doc.qt.io/qt-5/qjsengine.html#globalObject says:

Returns this engine's Global Object.

By default, the Global Object contains the built-in objects that are part of ECMA-262, such as Math, Date and String. Additionally, you can set properties of the Global Object to make your own extensions available to all script code. Non-local variables in script code will be created as properties of the Global Object, as well as local variables in global code.

Which seems to contradict the restriction listed above. There's also this:

Note: The globalObject() function cannot be used to modify the global object of a QQmlEngine. For more information about this, see JavaScript Environment Restrictions.

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

Comments

0

It appears that the problem was a bad build of 5.7.0-alpha. Upgrading to 5.7.0 release and rebuilding has removed this problem.

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.