集成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.