我有一个导入JavaScript库的QML文件:
import "qrc:/scripts/protobuf.js" as PB
在安装过程中此库modifies the 'global' object。简化,JS库是:
.pragma library
(function(global){
global.dcodeIO = global.dcodeIO || {};
global.dcodeIO.ProtoBuf = {}; // In reality, a complex object
})(this);
在Windows和Linux上,这可以按预期工作;稍后在我的QML文件中,我写了var ProtoBuf = PB.dcodeIO.ProtoBuf;
,它发现dcodeIO
属性被添加到' global'对象并正确地给了我需要的对象。
但是,在另一个平台上,相同的代码不起作用。我收到错误cannot read property ProtoBuf of undefined
。我将调试行添加到我的QML中,并查看:
console.log(PB.dcodeIO); //-> undefined
for (var k in PB) console.log(k,PB[k]); //-> (no enumerable properties logged)
然而,库中的JavaScript代码已加载并运行。如果我在上面链接的行之后添加console.log(global.dcodeIO)
,我会在库中看到[object Object]
。
有什么区别?如何确定Qt运行我的JavaScript文件的原因,但未成功将全局对象与PB
关联?
答案 0 :(得分:1)
JavaScript Environment Restrictions下列出的要点可能与此相关:
JavaScript代码无法修改全局对象。
在QML中,全局对象是常量 - 不能修改或删除现有属性,也不能创建新属性。
...
任何修改全局对象的尝试 - 无论是隐式还是显式 - 都会导致异常。如果未被捕获,这将导致打印警告,其中包括违规代码的文件和行号。
虽然你说它在两个平台上工作,但不是三分之一,所以也许你的用法是正确的,这是一个错误。
还有这一点:
全局代码在缩小的范围内运行。
虽然这一点似乎是关于从加载的脚本中访问QML对象。
关于这个问题,我一直不清楚文档。 http://doc.qt.io/qt-5/qjsengine.html#globalObject说:
返回此引擎的全局对象。
默认情况下,全局对象包含属于ECMA-262的内置对象,例如Math,Date和String。此外,您可以设置全局对象的属性,以使您自己的扩展可用于所有脚本代码。脚本代码中的非局部变量将被创建为全局对象的属性,以及全局代码中的局部变量。
这似乎与上面列出的限制相矛盾。还有this:
注意:globalObject()函数不能用于修改QQmlEngine的全局对象。有关此内容的更多信息,请参阅JavaScript环境限制。
答案 1 :(得分:0)
问题似乎是5.7.0-alpha
的错误构建。升级到5.7.0版本并重建已消除此问题。