Qml与Js调用
QML全局对象
• QML提供了全局的JavaScript对象Qt
• 在QML的任意部分都可以使用
• 在前面的例子中我们已经见过全局对象的使用了,MouseArea例子
:acceptedButtons: Qt.LeftButton | Qt.RightButton
• 提供了大量的函数:
• 创建QML类型:
• Qt.rect(…), Qt.rgba(…), Qt.point(…)
• 做一些其他的常用操作: • Qt.playSound(…), Qt.openUrlExternally(…), Qt.md5(…)
• 也提供了动态QML对象的创建,AJAX和本地数据访问的接口
在QML中使用JavaScript
• 在QML中使用JavaScript有如下一些限制和特点:
• JavaScript不能用于为全局对象添加新的成员
• 在声明变量时,可以省略“var”关键字
• 两种方法使用JavaScript
• Inline JavaScript
• 独立的javascript文件
Inline JavaScript
Item {
function factorial(a) {
a = parseInt(a);
if (a <= 0)
return 1;
else
return a * factorial(a - 1);
}
MouseArea {
anchors.fill: parent
onClicked: console.log(factorial(10))
}
}
独立 JavaScript 文件
factorial.js
在qml.qrc下新建js文件
.pragma library
function factorial(a) {
a = parseInt(a);
if(a <= 0) {
return 1;
}
else {
return a * factorial(a - 1);
}
}
main.qml文件
import "factorial.js" as MathFunctions
Item {
MouseArea {
anchors.fill: parent
onClicked: console.log(MathFunctions.factorial(10))
}
}
QML域(Scope)1/2
- 当创建了QML组件实例,QML自动会为他生成一个域(chain scope)
用于- JavaScript 的执行 (cf. JavaScript context in WWW)
- 属性的绑定
- 注意,同一个组件的不同实例可以有不同的域
- 当系统解析某个引用的时候,作用域的搜索是按照特定的顺序的
- JavaScript variables, functions and property bindings
- Attached properties or enumerations
QML域(Scope) 2/2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5QzMUU51-1615282989646)(D:/qt-projects/QmlJsDemo/Qml-域.jpg)]
QML域– 本地域 1/5
• 每个QML组件都有一个本地域
• 控件中的子空间也有自己的本地域
• 绝大多数的变量都是从本地域进行解析的
• 即使在本地域用也有一搜索顺序
• IDs
• Script methods
• Scope object
• Root object
QML脚本限制1/2
• 在JavaScript不能添加新的成员到QML全局对象中去
• 由于javascript处理未定义变量的方法,在无意间很可能就违背了找个限制
// Assuming that “a” has not been declared anywhere before, this code
// is illegal – JavaScript would implicitly try to create “a” as
// a member of the global object, which is not allowed.
a = 1;
for (var ii = 1; ii < 10; ++ii) { a = a * ii; }
console.log("Result: " + a);
// To make it legal, simply declare ”a” properly first:
var a = 1;
for (var ii = 1; ii < 10; ++ii) { a = a * ii; }
console.log("Result: " + a)
QML脚本限制2/2
• 在加载的时候,如有QML引用了一段外部的脚本文件,这个文件里
面有一段全局的代码,那么这段代码的执行的域将会是受限的
• 执行的域只包含全局对象和引入的脚本文件
• 这个时候不能保证所有的QML对象都已经被正确初始化了
• 所以全局的代码不能像平时那样正常的访问到QML对象及其属性
// Global code outside a function – works, because there are no
// references to any QML objects or properties
var colors = [ "red", "blue", "green", "orange", "purple" ];
// Invalid global code - the "rootObject" variable is undefined
var initialPosition = { rootObject.x, rootObject.y }
启动脚本
• 某些时候我们需要在应用开始执行时,运行一段初始化的代码
• 或者当一个控件初始化时运行
• 将这段代码放在外部的脚本文件中,并不是一个好的解决方案
• 当这段代码执行时,并非所有的QML的域都已经被完全初始化了
• 参考 ”QML脚本限制” 小节
• 最好的解决方案是采用Component 元素的onCompleted 这个
attached 属性
• 它会在整个控件完全初始化后被调用到
Rectangle {
function startupFunction() {
// ... startup code
}
Component.onCompleted: startupFunction();
}