QML- JavaScript 表达式在 QML 中使用
创始人
2024-06-02 14:52:17
0

Q 理论使用总结

  • 一、概述
  • 二、属性绑定中的JavaScript
  • 三、JavaScript在 signal handler 中的应用
  • 四、独立函数中的JavaScript
    • 1. QML里面JavaScript的自定义方法
    • 2. 定义在JavaScript文件中的函数
    • 3. 将信号连接到JavaScript函数
    • 五、在应用程序启动代码中使用JavaScript

一、概述

QML提供的JavaScript 的运行宿主环境可以运行有效的标准JavaScript 功能,如条件运算符、数组、变量设置和循环。除了标准的JavaScript属性之外,QML Global对象还包含一些辅助方法,用于简化构建ui以及与QML环境交互的过程。

QML提供的JavaScript环境比web浏览器中严格。例如,在QML中不能添加或修改JavaScript全局对象的成员。在常规的JavaScript中,有可能不小心使用了变量而没有声明它。在QML中,这将抛出异常,因此所有的局部变量都必须显式声明。有关从QML执行JavaScript代码的限制的完整描述,请参阅JavaScript环境限制。

QML文档的不同部分可以包含JavaScript代码,下面就是这些代码可能存在的情况:

  1. 属性绑定的Js: 这些JavaScript表达式描述了QML对象属性之间的关系。当属性的依赖关系发生变化时,属性也会根据指定的关系自动更新。
  2. 信号处理 signal handler程序的Js: 每当QML对象发出相关信号时,这些JavaScript语句就会被自动求值。
  3. 定义自定义方法的JS: 在QML对象体中定义的JavaScript函数成为该对象的方法。
  4. 独立的JavaScript资源(.js)文件: 这些文件实际上是独立于QML文档的,但是它们可以导入到QML文档中。可以在属性绑定、信号处理程序和自定义方法中使用在导入文件中定义的函数和变量。

二、属性绑定中的JavaScript

在下面的例子中,Rectangle的color属性依赖于 TapHandler 的 pressed 属性。这种关系可以用一个条件表达式来描述:

  import QtQuick 2.12Rectangle {id:  colorbuttonwidth:  200; height:  80;color:  inputHandler.pressed ? "steelblue" :  "lightsteelblue"TapHandler {id:  inputHandler}}

运行的效果如下:按下之后这个颜色更深
在这里插入图片描述在这里插入图片描述

事实上,任何JavaScript表达式 (无论多么复杂) 都可以用于属性绑定定义,只要表达式的结果是一个类型可以赋给属性的值。这包括副作用。然而,不鼓励使用复杂的绑定和副作用,因为它们会降低代码的性能、可读性和可维护性

定义属性绑定有两种方法:
第一种是最常见的方法如上面的示例所示
第二种(更少见的)方式是在命令式JavaScript代码中,将Qt.binding()函数返回的函数赋值给属性,如下所示:

import QtQuick 2.12Rectangle {id:  colorbuttonwidth:  200; height:  80;color:  "red"TapHandler {id:  inputHandler}Component.onCompleted:  {color = Qt.binding(function() { return inputHandler.pressed ? "steelblue" :  "lightsteelblue" });}
}

有关如何定义属性绑定的更多信息,请参阅属性绑定文档,有关绑定与值赋值的区别,请参阅属性赋值与属性绑定的文档。

三、JavaScript在 signal handler 中的应用

QML对象类型可以在某些事件发生时发出信号。这些信号可以通过信号处理函数来处理,这些函数可以由客户端定义来实现自定义的程序逻辑。

假设用Rectangle类型表示的按钮有一个TapHandler和一个Text标签。当用户按下按钮时,TapHandler会发出tap信号。客户端可以使用JavaScript表达式对onTapped处理程序中的信号做出反应。

QML引擎根据需要执行处理程序中定义的这些JavaScript表达式。通常,将信号处理程序绑定到JavaScript表达式以初始化其他事件或为属性赋值。

  import QtQuick 2.12Rectangle {id:  buttonwidth:  200; height:  80; color:  "lightsteelblue"TapHandler {id:  inputHandleronTapped:  {// arbitrary JavaScript expressionconsole.log("Tapped!")}}Text {id:  labelanchors.centerIn:  parenttext:  inputHandler.pressed ? "Pressed!" :  "Press here!"}}

四、独立函数中的JavaScript

程序逻辑也可以在JavaScript函数中定义。这些函数可以在QML文档中内联定义(作为自定义方法),也可以在导入的JavaScript文件中外部定义。

1. QML里面JavaScript的自定义方法

自定义方法可以在QML文档中定义,也可以从信号处理程序、属性绑定或其他QML对象中的函数中调用。这些方法通常被称为内联JavaScript函数,因为它们的实现包含在QML对象类型定义(QML文档)中,而不是在外部的JavaScript文件中。

下面是一个内联自定义方法的例子:

  import QtQuick 2.12Item {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发出tap信号时,fibonacci函数就会运行。

注意: 在QML文档中内联定义的自定义方法将暴露给其他对象,因此QML组件中根对象上的内联函数可以由组件外部的调用者调用。如果不希望这样做,可以将该方法添加到非根对象中,或者最好写在外部JavaScript文件中。

其实就是这个内联方法是有作用区域的。

2. 定义在JavaScript文件中的函数

工程实际中更推荐使用这个写法

重要的程序逻辑最好分离到一个单独的JavaScript文件中。这个文件可以使用import语句导入到QML中,就像QML模块一样。
例如,我们可以把前面例子中的fibonacci()方法移到一个名为fib.js的外部文件中,然后像下面这样访问它:

 import QtQuick 2.12import "fib.js" as MathFunctionsItem {TapHandler {onTapped:  console.log(MathFunctions.fibonacci(10))}}

有关将外部JavaScript文件加载到QML的更多信息,请阅读有关在QML中导入JavaScript资源的部分。

3. 将信号连接到JavaScript函数

发出信号的QML对象类型还为其信号提供默认信号处理程序,如前一节所述。然而,有时客户端希望在另一个QML对象发出信号时触发QML对象中定义的函数。这种情况可以通过信号连接来处理。

通过调用信号的connect()方法并将JavaScript函数作为参数传递,QML对象发出的信号可以连接到JavaScript函数。例如,下面的代码将TapHandler的tap信号连接到script.js中的jsFunction():

import QtQuick 2.12
import "script.js" as MyScriptItem {id:  itemwidth:  200; height:  200TapHandler {id:  inputHandler}Component.onCompleted:  {inputHandler.tapped.connect(MyScript.jsFunction)}
}
// script.jsfunction jsFunction() {console.log("Called JavaScript function!")
}

只要发出TapHandler的tap信号,jsFunction()就会被调用。

五、在应用程序启动代码中使用JavaScript

有时需要在应用程序(或组件实例)启动时运行一些命令式代码。虽然将启动脚本作为全局代码包含在外部脚本文件中很诱人,但这可能有严重的限制,因为QML环境可能尚未完全建立。例如,一些对象可能还没有创建,或者一些属性绑定可能还没有建立。要了解全局脚本代码的确切限制,请参阅JavaScript环境限制。

当QML对象的实例化完成时,它会发出Component.completed附加信号。对应组件中的JavaScript代码。onCompleted处理程序在对象实例化后运行。因此,编写应用程序启动代码的最佳位置是在组件中。在顶级对象的onCompleted处理程序中,因为当QML环境完全建立时,该对象会发出Component.completed。

例如:

import QtQuick 2.0Rectangle {function startupFunction() {// ... startup code}Component.onCompleted:  startupFunction();
}

QML文件中的任何对象——包括嵌套的对象和嵌套的QML组件实例——都可以使用这个附加属性。如果启动时要执行多个onCompleted()处理程序,它们将以未定义的顺序顺序运行。

同样,每个组件在被销毁之前都会发出一个destroy()信号。

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...