首页 > 编程语言 >QML概念及框架--继承JavaScript

QML概念及框架--继承JavaScript

时间:2023-02-07 10:34:59浏览次数:61  
标签:文件 -- 代码 JavaScript factorial QML 属性

QML推荐使用属性绑定和现有的QML元素来创建界面。为了允许执行更高级的行为,QML紧密集成了必要的JavaScript代码。QML中提供的JavaScript环境比在网页浏览器中的更严格。在QML中不可以添加或者修改JavaScript全局对象的成员,因为这样做可能会使一个没有经过声明的变量。在QML中会抛出一个异常,所以所有的局部变量都应该明确的声明。除了标准的JavaScript属性,在QML全局对象中还包含了一些很有用的函数,可以用来简化创建界面以及和QML环境进行交互。

1. 内联JavaScript

    较小的JavaScript函数可以和其他QML声明一起写在QML组件中。这些内联函数会像一般的函数一样添加到QML元素中:

 

import QtQuick 2.4

 

Item {

    function factorial(a) {

        a = parseInt(a)

        if(a <= 0)

            return 1;

        else

            return a * factorial(a-1)

    }

    MouseArea {

        anchors.fill: parent

        onClicked: console.log(factorial(10))

    }

}

    像一般函数一样,在一个QML组件根元素中的内联函数可以在组件外被调用。如果不想被被外部调用,那么这个函数可以添加到一个根元素以外的其他元素中,或者编写进一个外部的JavaScript文件中。

 

2. 分离的JavaScript文件

   大块的JavaScript代码需要写在一个独立的文件中,这些文件可以通过使用import语句导入QML文件中,就像导入QML模块一样。

前面代码中国的factorial()函数可以移动到一个外部名为“factorial.js”的文件中,然后进行访问:

 

import QtQuick 2.4

import "factorial.js" as MathFunctions

 

Item {

    MouseArea {

        anchors.fill: parent

        onClicked: console.log(MathFunctions.factorial(10))

    }

}

    相对和绝对的JavaScript路径都可以被导入。如果脚本文件不可访问,那么将发生错误。如果JavaScript需要从赢网络资源中获取,那么组件的状态会被设置为Loading,直到脚本被下载完毕。被导入的JavaScript文件总是使用as关键在来进行限定,每一个JavaScript文件的限定符必须是唯一的,在限定符合JavaScript文件之间是一对一映射的。

3. 代码隐藏(Code-Behind)实施文件

    大多数的JavaScript文件被导入一个QML是有状态的,它们经常作为该QML文件的逻辑实现。在这种情况下,为了使QML组件的实例有正确的行为,每个实例都需要JavaScript对象和状态的一个独立备份。导入一个JavaScript文件时的默认行为死为每一个QML组件实例提供一个唯一的、独立的备份。JavaScript代码和QML组件实例运行在相同的范围,因此可以访问和操作对象和声明的属性。

   一个QML中对JS文件中的值作了修改,再次调用时,这个值发生了变化。。。。。。

4. 无状态的JavaScript库

   一些JavaScript文件的行为更像库文件,它们提供了一组无状态的辅助函数来提供输入和计算输出,但是从来不直接操作QML组件实例。如果每一个QML组件实例都有一个这些库的拷贝,那么就会造成浪费。JavaScript程序员可以使用一个pragma来致命一个特定的文件是一个没有状态的库。

 

.pragma library

 

function factorial(a) {

    a = parseInt(a)

    if(a <= 0) {

        return 1;

    } else {

        return a * factorial(a -1)

    }

}

    这个prama声明必须出现在除了注释以外的所有JavaScript代码以前。虽然QML值可以作为函数的参数进行传递。不过这些共享的、无状态的库文件不能直接访问QML组件实例对象或属性。

 

5. 从其他JavaScript文件进行导入

    如果一个JavaScript文件需要使用定义在其他JavaScript文件中的函数,可以通过使用Qt.include()函数来导入其他的文件。这样会将其他文件中的所有函数导入到当前文件的命名空间中。例子:

 

import QtQuick 2.4

import "script.js" 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文件的内容:

 

 

Qt.include("factorial.js")

 

function showCalculations(value) {

    console.log("Call factorial() from script.js: ", factorial(value))

}

factorial.js文件的内容:

 

 

function factorial(a) {

    a = parseInt(a)

    if(a <= 0) {

        return 1;

    } else {

        return a * factorial(a -1)

    }

}

    注意,调用Qt.include()将会从factorial.js导入所有的函数到MyScript命名空间,这就意味着QML组件可以直接使用MyScript.factorial()来访问factorial()函数。

 

6. 在启动时运行JavaScript

    有时需要在应用程序(或者组件实例)启动时运行一些命令代码,但如果仅仅包含启动脚本作为全局代码,因为QML环境还没有完全建立起来,所以这样会有严重的局限,例如一些对象可能还没有被创建或者一些属性绑定还没有被运行。后面讲述的QML JavaScript限制一段中涵盖了全局脚本代码的确切限制。QMLComponent元素提供了一个附加的onCompleted属性可以用来在QML环境完全建立后切换到启动脚本代码的执行。

 

Rectangle {

    function startFunction(){

        //...startup code

    }

    

    Component.onCompleted: startupFunction();

}

    任何在QML文件中的元素,包含嵌套的元素和嵌套的QML组件实例,都可以使用这个附加属性。如果有多个onCompleted()处理器在启动时执行,它们会以未定义的顺序依次执行。类似的,Component::onDestruction附加属性会在组件销毁时触发。

 

7. 属性赋值与属性绑定

   当同时使用QML和JavaScript时,区分QML属性绑定和JavaScript赋值是很重要的。在QML中,使用“属性:值”语法来创建一个属性绑定。

 

Rectangle {

    width: otherItem.width //属性绑定,Rectangle的值会随otherItem.width的更改而更新

    

    Component.onCompleted: {

        width: otherItem.width  //属性赋值,不会调用QML的属性绑定

    }

}

8. 在JavaScript中接收QML信号

 

    要接收一个QML信号,可以使用信号的connect()函数将它关联到一个JavaScript函数上。

Item {

    id: item

    width: 200; height: 200

    

    MouseArea {

        id: mouseArea

        anchors.fill: parent

    }

    

    Component.onCompleted: {

        mouseArea.clicked.connect(MyScript.jsFunction)  //MouseArea的信号关联到script.js中的jsFunction()上

    }

}

9. QML JavaScript限制

 

    QML执行标准的JavaScript代码,会有下面的限制:

    (1) JavaScript代码不能修改全局对象

     在QML中,全局对象是一个常量,现有的属性不能够被修改和删除,也不能够创建新的属性。大多数的JavaScript程序并不是有意修改全局对象的,然而,JavaScript自动生成一个为声明的变量是全局对象的隐式修改,在QML中是非法的:

//a在作用链中不存在

//非法修改未声明的变量

a = 1;

for(var ii = 1; i < 10; ++ii)

    a = a * ii

console.log("Result: " + a)

    它可以简单修改为合法的代码:

 

 

a = 1;

for(var ii = 1; i < 10; ++ii)

    a = a * ii

console.log("Result: " + a);

    无论隐式的或者显式的对全局对象的修改都会导致一个异常

 

    (2) 全局代码运行在一个缩小的范围

    在启动时,如果QML文件包含一个外部的JavaScript文件和“全局”代码,它会只包含该外部文件和这个全局对象的范围内执行。也就是说,它不会像通常那样访问QML对象和属性。全局代码只访问脚本中的局部变量是允许的。

 

//有效的全局代码

var colors = ["red", "blue", "green", "orange", "purple"]

    非法的全局代码--“rootObject”变量未定义

 

 

var initialPosition = {rootObject.x, rootObject.y}

    存在此限制是因为QML环境尚未被完全建立。要宰环境完全启动后运行后运动代码。

 

    (3) 目前在QML中this值是未定义的,要引用任何元素,可以使用其id。

 

Item {

    width: 200; height: 200

 

    function mouseAreaClicked(area) {

        console.log("Clicked in area at: " + area.x + "," + area.y)

    }

    //因为this未定义,所以下面的代码不会工作

    MouseArea{

        height: 50; width: 200

        onClicked: mouseAreaClicked(this)

    }

    //这样可以将area2传递给函数

    MouseArea {

        id: area2

        y: 50; height: 50; width: 200

        onClicked: mouseAreaClicked(area2)

    }

}

 

from:  https://blog.csdn.net/u012419303/article/details/45896263

 

标签:文件,--,代码,JavaScript,factorial,QML,属性
From: https://www.cnblogs.com/im18620660608/p/17097510.html

相关文章

  • OushuDB数据库基本用法(下)
    一个数据库包含多个模式(schema),而一个模式可以包含多种命名对象,比如表,数据类型,函数,操作符等。同一个对象名字可以用在不同的模式中而不产生冲突。比如schema1中可以包含表tes......
  • 产品力狂飙|Coremail荣登第五版《CCSIP2022中国网络安全行业全景册》
    2023年2月1日,FreeBuf咨询正式发布 《CCSIP(ChinaCyberSecurityPanorama)2022中国网络安全行业全景册(第五版)》。第五版全景图仍将以PDR网络安全模型为基础,并参考IPDRR安全......
  • 里氏转换
     staticvoidMain(string[]args){/*里氏转换*1、子类可以赋值给父类(如果一个有一个方法需要父类作为参数,我们可......
  • 偶数科技:基于OushuDB的新一代云原生湖仓一体为企业助力
    实时性数据分析需求暴增,偶数湖仓一体为企业助力在愈发复杂的大数据场景下,数据仓库与数据湖各自的弊端开始显现,湖仓一体架构走向舞台中央。在国外有两种流行的实现数据湖仓......
  • 浅谈容器
      >Collencttion分三大类List,Set,Queue(实现了很多多线程,任务装载,为线程池高并发做准备) >Map ......
  • OushuDB连接带kerberos的HDFS
    一.KDC上的操作1.登录KDCserver,将Kerberos配置文件/etc/krb5.conf分发至KDW每个节点:scp/etc/krb5.conf10.0.5.58:/etc/scp/etc/krb5.conf10.0.5.146:/etc/scp/etc/......
  • OushuDB 创建和管理表空间
    OushuDB里的表空间允许数据库管理员在文件系统里定义那些代表数据库对象的文件存放位置。一旦创建了表空间,那么就可以在创建数据库对象的时候引用它。通过使用表空间,管理......
  • QML教程(一)基础语法
    目录一、导入二、对象声明 三、对象属性1.声明对象属性2.信号属性3.方法属性4.附加属性略 5.枚举属性 6.对象属性赋值四、自定义对象  一、导入模块导......
  • Spring—Spring MVC 全解析
    处理流程SpringMVC处理流程.PNG用户发送请求至前端控制器DispatcherServlet;DispatcherServlet收到请求调用HandlerMapping处理器映射器;处理器映射器找到具体的处理器(......
  • pytest--allure报告中添加用例详情
    前言前面介绍了如何生成allure的报告,看着allure的页面非常好看,但是感觉少了一些内容,allure还可以增加一些用例详情内容,这样让我们的报告看着更加绚丽。allure增加用例详......