QML 文档中的 JavaScript 表达式
QML 提供的JavaScript 宿主环境可运行有效的标准 JavaScript 结构,例如条件运算符、数组、变量赋值和循环。除了标准的 JavaScript 属性外,QML 全局对象还包含许多辅助方法,这些方法简化了 UI 的构建以及与 QML 环境的交互。
QML 提供的 JavaScript 环境比 Web 浏览器中的更为严格。例如,在 QML 中,您无法向 JavaScript 全局对象添加或修改其成员。在常规 JavaScript 中,可能会因未声明变量就直接使用而无意中执行此类操作。但在 QML 中,这将引发异常,因此所有局部变量都必须显式声明。 有关从 QML 执行的 JavaScript 代码所受限制的完整说明,请参阅“JavaScript 环境限制”。
QML 文档的各个部分均可包含 JavaScript 代码:
- 属性绑定的主体。这些 JavaScript 表达式描述了 QML对象属性之间的关系。当某个属性的依赖项发生变化时,该属性也会根据指定的关系自动更新。
- 信号处理程序的主体。每当 QML 对象发出相关信号时,这些 JavaScript 语句都会被自动求值。
- 自定义方法的定义。在 QML 对象主体内定义的 JavaScript 函数将成为该对象的方法。
- 独立的JavaScript 资源 (.js) 文件。这些文件实际上与 QML 文档是分离的,但可以导入到 QML 文档中。在导入的文件中定义的函数和变量可在属性绑定、信号处理程序和自定义方法中使用。
属性绑定中的 JavaScript
在下面的示例中,Rectangle 的color 属性依赖于TapHandler 的pressed 属性。这种关系通过条件表达式描述:
import QtQuick 2.12
Rectangle {
id: colorbutton
width: 200; height: 80;
color: inputHandler.pressed ? "steelblue" : "lightsteelblue"
TapHandler {
id: inputHandler
}
}实际上,只要表达式的结果是可赋值给该属性的类型,任何 JavaScript 表达式(无论多么复杂)都可用于属性绑定定义中。这包括副作用。但是,不建议使用复杂的绑定和副作用,因为它们会降低代码的性能、可读性和可维护性。
定义属性绑定有两种方法:最常见的方法如前面的示例所示,是在属性初始化中进行。第二种(且更为罕见)的方法是在命令式 JavaScript 代码中,将由 `Qt.binding()` 函数返回的函数赋值给该属性,如下所示:
import QtQuick 2.12
Rectangle {
id: colorbutton
width: 200; height: 80;
color: "red"
TapHandler {
id: inputHandler
}
Component.onCompleted: {
color = Qt.binding(function() { return inputHandler.pressed ? "steelblue" : "lightsteelblue" });
}
}有关如何定义属性绑定的更多信息,请参阅属性绑定文档;关于绑定与值赋值的区别,请参阅《属性赋值与属性绑定》文档。
信号处理程序中的 JavaScript
QML 对象类型可在发生特定事件时发出信号。这些信号可由信号处理函数进行处理,客户端可定义这些函数以实现自定义程序逻辑。
假设一个由 Rectangle 类型表示的按钮有一个TapHandler 和一个 Text 标签。当用户按下该按钮时,TapHandler 会发出其tapped 信号。客户端可以在onTapped 处理程序中使用 JavaScript 表达式来响应该信号。 QML 引擎会根据需要执行处理程序中定义的这些 JavaScript 表达式。通常,信号处理程序会与 JavaScript 表达式绑定,以触发其他事件或赋值属性。
import QtQuick 2.12
Rectangle {
id: button
width: 200; height: 80; color: "lightsteelblue"
TapHandler {
id: inputHandler
onTapped: {
// arbitrary JavaScript expression
console.log("Tapped!")
}
}
Text {
id: label
anchors.centerIn: parent
text: inputHandler.pressed ? "Pressed!" : "Press here!"
}
}有关信号和信号处理程序的更多详细信息,请参阅以下主题:
独立函数中的 JavaScript
程序逻辑也可以在 JavaScript 函数中定义。这些函数可以在 QML 文档中内联定义(作为自定义方法),也可以在导入的 JavaScript 文件中外部定义。
自定义方法中的 JavaScript
可以在 QML 文档中定义自定义方法,并可从信号处理程序、属性绑定或其他 QML 对象中的函数中调用这些方法。此类方法通常被称为内联 JavaScript 函数,因为其实现包含在 QML 对象类型定义(QML 文档)中,而非外部 JavaScript 文件中。
以下是一个内联自定义方法的示例:
import QtQuick 2.12
Item {
function fibonacci(n){
var arr = [0, 1];
for (var i = 2; i < n + 1; i++)
arr.push(arr[i - 2] + arr[i -1]);
return arr;
}
TapHandler {
onTapped: console.log(fibonacci(10))
}
}每当TapHandler 发出tapped 信号时,fibonacci函数就会被调用。
注意: 在 QML 文档中内联定义的自定义方法会 向其他对象公开,因此 QML 组件中根对象上的内联函数可能会被组件外部的调用方调用。如果希望避免这种情况,可以将该方法添加到非根对象上,或者更推荐将其编写在外部 JavaScript 文件中。
有关在 QML 中使用 JavaScript 定义自定义方法的更多信息,请参阅QML 对象属性文档。
在 JavaScript 文件中定义的函数
较复杂的程序逻辑最好拆分到单独的 JavaScript 文件中。该文件可通过 `import ` 语句导入到 QML 中,与 QML模块的导入方式类似。
例如,前文示例中的fibonacci() 方法可以移至名为fib.js 的外部文件中,并按如下方式调用:
import QtQuick 2.12
import "fib.js" as MathFunctions
Item {
TapHandler {
onTapped: console.log(MathFunctions.fibonacci(10))
}
}有关将外部 JavaScript 文件加载到 QML 中的更多信息,请参阅“在 QML 中导入 JavaScript 资源”一节。
将信号连接到 JavaScript 函数
如前一节所述,会发出信号的 QML 对象类型为其信号提供了默认信号处理程序。但有时,客户端希望在另一个 QML 对象发出信号时触发定义在该 QML 对象中的函数。此类场景可通过信号连接来处理。
可以通过调用信号的connect() 方法并将JavaScript函数作为参数传递,将QML对象发出的信号连接到JavaScript函数。例如,以下代码将TapHandler 的tapped 信号连接到script.js 中的jsFunction() :
| |
每当TapHandler 的tapped 信号被触发时,就会调用jsFunction() 方法。
有关更多信息,请参阅《将信号连接到方法和信号》。
应用程序启动代码中的 JavaScript
有时需要在应用程序(或组件实例)启动时运行一些命令式代码。虽然将启动脚本作为全局代码包含在外部脚本文件中看似诱人,但这可能会带来严重的限制,因为 QML 环境可能尚未完全建立。 例如,某些对象可能尚未创建,或者某些属性绑定可能尚未建立。有关全局脚本代码的具体限制,请参阅《JavaScript 环境限制》。
当 QML 对象的实例化完成时,该对象会发出Component.completed 附加信号。相应Component.onCompleted 处理程序中的 JavaScript 代码将在对象实例化后运行。因此,编写应用程序启动代码的最佳位置是顶级对象的Component.onCompleted 处理程序中,因为当 QML 环境完全建立时,该对象会发出Component.completed 信号。
例如:
import QtQuick 2.0
Rectangle {
function startupFunction() {
// ... startup code
}
Component.onCompleted: startupFunction();
}QML 文件中的任何对象(包括嵌套对象和嵌套的 QML 组件实例)均可使用此附加属性。如果启动时需要执行多个onCompleted() 处理程序,它们将按未定义的顺序依次执行。
同样,每个Component 在被销毁前都会发出一个destruction()信号。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.