QML 集成js和qml

集成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!"
    }
}

3.自定義方法定義

內聯定義函數(在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全局對象

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章