集成QML和JavaScript
允许将各种表达式和方法定义为JavaScript函数。它还允许用户导入JavaScript文件并使用这些导入提供的功能。
JavaScript表达式
QML具有深层的JavaScript集成,并允许在JavaScript中定义信号处理程序和方法。QML的另一个核心功能是能够使用属性绑定指定和加强对象属性之间的关系,该属性绑定也是使用JavaScript定义的。
QML文档的以下部分可以包含JavaScript代码:
1. 属性绑定的主体
//属性绑定有两种方式,1.属性初始化 。2.js中使用Qt.binding()
import QtQuick 2.12
Rectangle {
id: colorbutton
width: 200; height: 80;
color: inputHandler.pressed ? "steelblue" : "lightsteelblue" //属性初始化进行绑定
TapHandler {
id: inputHandler
}
}
//使用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" });
}
}
2. 信号处理程序的主体
import QtQuick 2.12
Rectangle {
id: button
width: 200; height: 80; color: "lightsteelblue"
TapHandler {
id: inputHandler
onTapped: { //信号处理时使用js时行逻辑处理
// arbitrary JavaScript expression
console.log("Tapped!")
}
}
Text {
id: label
anchors.centerIn: parent
text: inputHandler.pressed ? "Pressed!" : "Press here!"
}
}
内联定义函数(在QML对像内部定义)
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))
}
}
注意,以下示例代码
Column{
width:200
height:200
anchors.left: col1.right
leftPadding: add(100,10) //add可用
function add( a, b) //同级作用域可用,如果放到根目录下,则所有对象均可使用
{
return a+b;
}
TextInput{
id:ti
text:""+add(10,10) //add不可用
}
Text {
id: t
text: ti.text
}
4.独立的JavaScript资源(.js)文件。
程序逻辑最好分离到一个单独的JavaScript文件中。可以使用import
将该文件导入QML 。
import QtQuick 2.12
import "fib.js" as MathFunctions //导入js文件并起一个别名
Item {
TapHandler {
onTapped: console.log(MathFunctions.fibonacci(10))
}
}
将信号连接到JavaScript函数
import QtQuick 2.12
import "script.js" as MyScript
Item {
id: item
width: 200; height: 200
TapHandler {
id: inputHandler
}
Component.onCompleted: {
inputHandler.tapped.connect(MyScript.jsFunction)
}
}
function jsFunction() {
console.log("Called JavaScript function!")
}
应用程序启动代码中的JavaScrip
编写应用程序启动代码的最佳位置是在Component.onCompleted
顶级对象的处理程序中,因为Component.completed
在完全建立QML环境时,此对象会发出。
import QtQuick 2.0
Rectangle {
function startupFunction() {
// ... startup code
}
Component.onCompleted: startupFunction();
}
JavaScript资源
js资源有两种方式,一种有状态,每一个对象一个独立的Js句柄,另一种为无状态,共享库:
// MyButton.qml
import QtQuick 2.0
//每创建一个MyButton就会创建一个新的my_button_impl.js,每个对象的js对象是独立的。
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 所有对象都有一个自已的clickCount
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);
}
}
另一种为无状态,共享库,所有引用js的对象共享同一对象
// 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;
}
尽管可以将QML值作为函数参数传递,但共享它们时,.pragma库文件无法直接访问QML组件实例对象或属性
JavaScript导入
QML导入Js
import "ResourceURL" as Qualifier
//例子
import "jsfile.js" as Logic
//JavaScript资源的限定符必须以大写字母开头,并且必须是唯一的,并且不能同名(与内置对象)
js中导入
QtQuick 2.0允许导入其他JavaScript资源以及QML类型的名称空间
导入js
//语法1 .import "filename.js" as Qualifier
//语法2 import * as MathFunctions from "factorial.mjs";
import QtQuick 2.0
import "script.mjs" as MyScript
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
MyScript.showCalculations(10)
console.log("Call factorial() from QML:",
MyScript.factorial(10))
}
}
}
// script.js
import { factorial } from "factorial.mjs"
function showCalculations(value) {
console.log(
"Call factorial() from script.js:",
factorial(value));
}
// factorial.mjs
export function factorial(a) {
a = parseInt(a);
if (a <= 0)
return 1;
else
return a * factorial(a - 1);
}
Js导入QML模块
//语法:.import TypeNamespace MajorVersion.MinorVersion as Qualifier
//例子:
.import Qt.test 1.0 as JsQtTest
var importedEnumValue = JsQtTest.MyQmlObject.EnumValue3
JavaScript主机环境
QML引擎提供了一个JavaScript环境,该环境与Web浏览器提供的JavaScript环境有所不同。某些限制适用于在环境中运行的代码,并且QML引擎在根上下文中提供了JavaScript开发人员可能不熟悉的各种对象。
这些限制和扩展记录在QML引擎提供的JavaScript主机环境的说明中。
QML全局对象
- The Qt object: This object is specific to QML, and provides helper methods and properties specific to the QML environment.
- qsTr(), qsTranslate(), qsTrId(), QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRID_NOOP() functions: These functions are specific to QML, and provide translation capabilities to the QML environment.
- gc() function: This function is specific to QML, and provides a way to manually trigger garbage collection.
- print() function: This function is specific to QML, and provides a simple way to output information to the console.
- The console object: This object implements a subset of the FireBug Console API.
- XMLHttpRequest, DOMException: These objects implement a subset of the W3C XMLHttpRequest specification.