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全局对象

 

 

 

 

 

 

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