在QML中定义JS资源- Stateless library的意义

一,概述 QML与JS的结合

可以在JavaScript中定义QML应用的程序逻辑。JS既可以在QML文档中定义比如

Text{

      text:{

         function fn(a,b){

              return  a+b

                        }

       fn(1,2)

                }

}

也可以导入单独的js文件。(作为QML的JavaScript资源)

在QML中,支持两种不同的js资源:基于执行的JS文件、共享的JS文件。

这两种文件都可以导入到其他的js资源中,导入到QML中。

二,基于执行的JS文件

大多数导入到QML文件的JS文件,都是为了对QML文档中的元素进行操作,在这些情况下,每个QML组件实例都需要一个对应的JS对象的复件,这样每个对象实例才会显示正确。

默认情况下,当QML组件类型导入JS文件的时候,一旦QML组件类型实例化,那么每一个实例都会导入唯一的单独的JS文件复件。如果在这个JS文件中,没有import其他的js文件或者模块,那么它的代码运行作用域是和QML组件实例是相同的,可以直接接入和操作QML中声明的属性和对象。否则,它将有自己唯一的作用域,需要的时候,将QML组件作为js文件函数的参数进行操作。

基于执行的js文件 ,示例如下:

MyButton.qml类型

import QtQuick2.0
import "my_button_imp.js" as Logic//将为每一个MyButton实例,复制一个js

Rectangle{
   id:rect
   width:200;height:100
   color:"red"
 
   MouseArea{
       id:mousearea
       anchors.fill:parent
      onClicked:{
        Logic.onClicked(rect)
     }
  }
}

my_button_imp.js

var clickCount=0  //这种状态将分配到每一个实例中,也就是说分开的,
//所以没一个实例的变量都为0
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
  }
}

一般来说,简单的逻辑直接写在QML文件中,复杂的逻辑单独写在js文件中。

总结:每次实例化单个的QML组件,组件中使用的js文件也会为这个实例单独复制出一份。

三,共享js文件(库)

默认情况下,导入到QML文件中js文件,会共享他们的上下文(作用域),这就意味着js可以接入QML文件中的对象(Button,Text等),并且可以修改他们,因此,每一个QML都会对应唯一的js实例,尽管js的内容是相同的。然而,一些js文件不需要保持状态(比如clickCount=0这种变量,不需要每个调用JS文件的QML组件关心这个是不是为0),并且行为可以重用。这类js文件,对使用它的环境没有要求,也无需导入任何数据。通过使用语句”.pragma library“来标识这一类的js文件,不仅可以加速QML组件的实例化,并且可以节省大量的内存。示例如下

 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文件可以导入factorial.js文件,并且都可以使用其中的factorial()和factorialCallCount()函数。这种方式的在多个QML文件中,js文件是共享的,只有一个,所以当某个QML文件第一次调用这个js文件的时候,factorialCallCount返回的不一定是0,因为factorialCount可能已经被其他的QML组件修改了,但是没关系,主要使用的是factorial这个函数,而factorialCount只是用来记录次数而已。

示例如下

Calculator.qml

 // Calculator.qml
 import QtQuick 2.0
 import "factorial.js" as FactorialCalculator // This JavaScript resource is only
                                              // ever loaded once by the engine,
                                              // even if multiple instances of
                                              // Calculator.qml are created.

 Text {
     width: 500
     height: 100
     property int input: 17
     text: "The factorial of " + input + " is: " 
+ FactorialCalculator.factorial(input)
 }

一旦共享,js文件将不能访问和修改QML文件中的对象,尽管可以传递QML文件对象的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值