QML自学之路(五)-QML作用域

8 篇文章 0 订阅
3 篇文章 0 订阅
本文详细介绍了QML的文档作用域和JavaScript作用域。QML文档作用域包括根对象属性和ID属性,作用域层级允许子对象访问祖先属性。JavaScript作用域遵循标准JS规则,但在QML中可以访问导入的对象和资源。绑定作用域在属性绑定中允许直接访问对象属性,如示例中PathView.delegate的scale属性需通过Rectangle的root前缀来正确引用。
摘要由CSDN通过智能技术生成

QML作用域个人认为是一个比较复杂的主题。本文将结合自己理解,对QML文档作用域及JavaScript作用域分别进行介绍。

一、QML文档作用域

每个QML文档定义了一个作用域,这个作用域包含了:根对象所有属性以及文档中包含的所有id属性。通过以下示例进一步说明文档作用域:

Item {
    property string title

    Text {
        id: titletype
        text: "<b>" + title + "</b>"
        font.pixelSize: 22
        anchors.top: parent.top
    }

    Text {
        text: titletype.text
        font.pixelSize: 18
        anchors.bottom: parent.bottom
    }
}

在以上例子中,包含了一个QML文档,这个文档中定义了一个对象类型。在这类型定义中,包含了一个Item类型的根对象。以及两个Text类型的子对象。因此,这个文档定义的逻辑作用域为:Item类型的所有属性、title属性以及第一个Text对象的id属性。

当一个对象类型被实例化时,这个对象的文档作用域会被挂接到使用它的对象的文档作用域上,从而形成了一个作用层级。因此,这个被实例化的对象可以访问它的祖先作用域中的属性及id。这也是所谓的QML动态作用域。通过以下例子来进一步解释:

// TitlePage.qml
import QtQuick 2.0
Item {
    property string title

    TitleText {
        size: 22
        anchors.top: parent.top
    }

    TitleText {
        size: 18
        anchors.bottom: parent.bottom
    }
}

// TitleText.qml
import QtQuick 2.0
Text {
    property int size
    text: "<b>" + title + "</b>"
    font.pixelSize: size
}

在以上示例中,TitleText.qml文件包含了一个QML文档,这个文档定义了TitleText对象类型,同时也定义了一个作用域。在TitlePage.qml文件也包含了一个QML文档,这个文档也定义了一个作用域。在这个文档中使用了TitleText对象类型创建了两个子对象。因此,在QML运行时,TitleText作用域会挂接到TitlePage作用域上,形成一个作用域层级,在TitleText文档中使用了title属性,QML引擎在当前作用域中没有找到这个属性,它会继续在上层作用域中继续查找。因为TitlePage作用域中包含title属性,所以,会将这个引用解析为对TitlePage的title属性。

以下是一个包含内联组件的例子:

Item {
    property color defaultColor: "blue"

    ListView {
        delegate: Component {
            Rectangle {
                color: defaultColor
            }
        }
    }
}

在这个例子中,Component类型包含了一个QML文档,这个QML文档定义了一个新的对象类型。ListView中创建了一个这个类型的对象,并将它赋值给了delegate属性。这个内联QML文档的作用域被挂接到外层文档的作用域上。因此在Component包含的QML文档中可以使用defaultColor属性。

二、javaScript作用域

在QML程序中编写javaScript代码时,可以按照javaScript作用域知识来确定作用域。例如:

QtObject {
    property int a: 3
    property int b: 9

    function addConstant(b) {
        var a = 13;
        return b + a;
    }
}

在以上程序中,addConstant函数内部的b变量为传入参数b,而不是qtObject类型对象的b属性。

QML对原始javaScript作用域进行了扩展,当QML文档中包含import语句时,javaScript代码可以对引入的对象类型,javaScript资源进行访问。例如:

import QtQuick 2.0
import "code.js" as Code

ListView {
    snapMode: ListView.SnapToItem

    delegate: Component {
        Text {
            elide: Text.ElideMiddle
            text: "A really, really long string that will require eliding."
            color: Code.defaultColor()
        }
    }
}

在这个程序中,Text类型对象的color属性通过一个javaScript表达式为其赋值。而这个javaScript表达式调用的是被引入的javaScript资源(code.js)中的函数。

当javaScript代码出现在属性绑定中,作用域规则稍有不同。在QML程序中,如果一个对象含有属性绑定,那么这个对象被称作绑定作用域对象。绑定javaScript表达式中可以直接访问绑定作用域对象中的属性,无需在属性前添加前缀。例如:

Item {
    anchors.left: parent.left
}

在以上代码中,Item类型的对象是一个绑定作用域对象。绑定表达式中,可以直接访问Item类型对象的parent属性,而无需添加任何前缀。

当需要在绑定表达式中访问附加属性时,需要注意特别注意。例如:

PathView {
    delegate: Component {
        Rectangle {
            id: root
            Image {
                scale: root.PathView.scale
            }
        }
    }
}

在以上代码中,Image类型的对象是一个绑定作用域对象。绑定表达式中需要访问的是Rectangle

类型对象的附加属性PathView.scale。如果,不加root前缀,那么绑定表达式中访问的将是Image类型对象的PathView.scale,而这个属性是不存在的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值