Toggle Light / Dark / Auto color theme
Toggle table of contents sidebar
在QML中定义JavaScript资源
描述如何在QML中定义JavaScript文件以供使用
QML应用程序的程序逻辑可以用JavaScript定义。JavaScript代码可以在QML文档中内联定义,也可以分离到JavaScript文件中(在QML中称为JavaScript Resources
)。
QML支持两种不同类型的JavaScript资源:代码隐藏实现文件和共享(库)文件。这两种JavaScript资源都可以被其他JavaScript资源导入 ,或者包含在QML模块 中。
代码隐藏实现资源
大多数导入到QML文档中的JavaScript文件都是为导入它们的QML文档提供有状态的实现。在这些情况下,文档中定义的QML对象类型的每个实例都需要一个单独的JavaScript对象和状态的副本,以便正确运行。
导入JavaScript文件时的默认行为是为每个QML组件实例提供一个唯一的、隔离的副本。如果该JavaScript文件没有使用.import
语句导入任何资源或模块,其代码将在与QML组件实例相同的范围内运行,因此可以访问和操作在该QML组件中声明的对象和属性。否则,它将拥有自己唯一的作用域,并且如果需要,应将QML组件的对象和属性作为参数传递给JavaScript文件的函数。
以下是一个代码隐藏实现资源的示例:
// MyButton . qml
import QtQuick 2.0
import "my_button_impl.js" as Logic // A new instance of this JavaScript resource
// is loaded for each instance of Button . qml .
Rectangle {
id : rect
width : 200
height : 100
color : "red"
MouseArea {
id : mousearea
anchors . fill : parent
onClicked : Logic . onClicked ( rect )
}
}
// my_button_impl . js
var clickCount = 0 ; // this state is separate for each instance of MyButton
function onClicked ( button ) {
clickCount += 1 ;
if (( clickCount % 5 ) == 0 ) {
button . color = Qt . rgba ( 1 , 0 , 0 , 1 );
} else {
button . color = Qt . rgba ( 0 , 1 , 0 , 1 );
}
}
一般来说,简单的逻辑应该在QML文件中内联定义,但更复杂的逻辑应该分离到代码背后的实现资源中,以提高可维护性和可读性。
共享的JavaScript资源(库)
默认情况下,从QML导入的JavaScript文件与QML组件共享其上下文。这意味着JavaScript文件可以访问相同的QML对象并可以修改它们。因此,每个导入都必须拥有这些文件的唯一副本。
上一节 介绍了 JavaScript 文件的有状态导入。然而,一些 JavaScript 文件是无状态的,更像是可重用的库,因为它们提供了一组辅助函数,这些函数不需要从导入它们的任何地方获取任何内容。如果使用特殊的 pragma 标记这些库,可以节省大量内存并加快 QML 组件的实例化,如下例所示。
// factorial . js
. pragma library
var factorialCount = 0 ;
function factorial ( a ) {
a = parseInt ( a );
// factorial recursion
if ( a > 0 )
return a * factorial ( a - 1 );
// shared state
factorialCount += 1 ;
// recursion base - case .
return 1 ;
}
function factorialCallCount () {
return factorialCount ;
}
pragma声明必须出现在任何JavaScript代码之前,不包括注释。
请注意,多个QML文档可以导入"factorial.js"
并调用它提供的factorial和factorialCallCount函数。JavaScript导入的状态在导入它的QML文档之间是共享的,因此,即使在一个从未调用factorial函数的QML文档中调用factorialCallCount函数,其返回值也可能不为零。
例如:
// Calculator . qml
import QtQuick 2.0
import "factorial.js" as FactorialCalculator // This JavaScript resource is only
// ever loaded once by the engine ,
// even if multiple instances of
// Calculator . qml are created .
Text {
width : 500
height : 100
property int input : 17
text : "The factorial of " + input + " is: " + FactorialCalculator . factorial ( input )
}
由于它们是共享的,.pragma库文件不能直接访问QML组件实例对象或属性,尽管QML值可以作为函数参数传递。