QML 静态值与属性绑定

简述

可以为 QML 对象中的属性分配两种类型的值 - 静态值和绑定表达式,后者也称为属性绑定。

  • 静态值:一个不依赖于其他属性的常数值。
  • 绑定表达式:一个用于描述属性间依赖关系的 JavaScript 表达式。

属性绑定是 QML 的一个核心特性,允许指定不同对象属性之间的依赖关系。当属性的依赖项(属性绑定中的变量)的值发生改变时,属性将根据指定的关系自动更新。

| 版权声明:一去、二三里,未经博主允许不得转载。

静态值

所谓静态值,就是一个不依赖于其他属性的常数值。例如:width : 100,其中 100 就是一个静态值。

下面的示例,将 Rectangle 的 width 和 height 均分配为静态值。

这里写图片描述

import QtQuick 2.3

Rectangle {
    // 初始化赋值 - 静态值
    width: 200
    height: 200

    Rectangle {
        // 初始化赋值 - 静态值
        width: 100
        height: 100
        color: "blue"
    }
}

既然蓝色 Rectangle 的 width 和 height 都是静态值,那么当父 Rectangle 大小发生变化时,蓝色 Rectangle 的大小必然不会改变。

属性绑定

属性绑定,简单的理解就是一个绑定表达式,用于描述属性之间的依赖关系。例如:width : parent.width / 2

QML 引擎作为属性绑定的幕后推手,在时刻监视属性的依赖项,当检测到任何依赖项的值发生改变后,就会自动重新计算绑定表达式,并为属性分配新的结果。

使用属性绑定

要创建一个属性绑定,需要为属性分配一个 JavaScript 表达式,该表达式将计算所需的值。最简单的情况,绑定是对另一属性的引用。

下面的示例,将蓝色 Rectangle 的 width 绑定到其 parent 的 width:

这里写图片描述

import QtQuick 2.3

Rectangle {
    width: 200
    height: 200

    Rectangle {
        width: parent.width
        height: 100
        color: "blue"
    }
}

每当父 Rectangle 的 width 发生变化,蓝色 Rectangle 的 width 就会自动更新为相同的值。

绑定可以包含任何有效的 JavaScript 表达式或语句,因为 QML 使用了一个符合标准的 JavaScript 引擎。绑定可以访问对象属性、调用方法、并使用内置的 JavaScript 对象(例如:Date、Math)。下面是上述示例的其他可能性绑定:

// 访问对象属性
width: parent.width / 2

// 使用内置的 JavaScript 对象 Math
width: Math.min(parent.width, parent.height)

// 使用三目运算符
width: parent.width > 100 ? parent.width : parent.width /2

// if-else 代码块中的 return 关键字可有可无
width: {
    if (parent.width > 100)
        return parent.width
    else
        return parent.width / 2
}

// 调用方法
height: someMethodThatReturnsWidth()

在语法上,绑定允许具有任意复杂性(例如:涉及多行或命令循环)。但是,如果绑定过于复杂,可能会降低代码性能、可读性、和可维护性。比较好的方法是:重新设计具有复杂绑定的组件,或者至少将绑定转换为单独的函数。

从 JavaScript 创建属性绑定

具有绑定的属性将根据需要自动更新,但是,如果稍后从 JavaScript 语句为该属性重新分配一个静态值,则将会移除绑定。

例如,下面的蓝色 Rectangle 最初确保其 width 总是其 parent 的 width 的 1/4。但是,当按下空格键时,parent.width / 2 将作为静态值赋值给 width。随后,即使其 parent 的 width 发生变化,其 width 也将保持不变,因为静态值的分配移除了绑定。

这里写图片描述

import QtQuick 2.3

Rectangle {
    width: 200
    height: 200

    Rectangle {
        id: rect
        width: parent.width / 4
        height: 50
        color: "blue"

        focus: true
        Keys.onSpacePressed: {
            width = parent.width / 2
        }
    }
}

如果目的是为了给蓝色 Rectangle 一个固定的 width 并停止自动更新,那么这没有任何问题。但是,如果是为了给 width 和其 parent 的 width 建立一个新的关系,那么新的绑定表达式必须被包裹在 Qt.binding() 函数中:

这里写图片描述

//...
Keys.onSpacePressed: {
    width = Qt.binding(function() { parent.width / 2 })
}
//...

现在,按下空格键后,矩形的高度将继续自动更新,始终为其 parent 的 width 的 1/2。

在属性绑定中使用 this

当从 JavaScript 创建一个属性绑定时,this 关键字可用于引用接收绑定的对象,这有助于解决属性名称产生的歧义。

例如,下面的 Component.onCompleted 处理程序在 Item 的范围内定义。此范围内,width 是指 Item 的 width,而不是 Rectangle 的 width。要将 Rectangle 的 height 绑定到其自身的 width,绑定表达式必须显式地引用 this.width(或者 rect.width):

import QtQuick 2.3

Item {
    width: 200
    height: 200

    Rectangle {
        id: rect
        width: 100
        color: "blue"
    }

    Component.onCompleted: {
        rect.height = Qt.binding(function() { return this.width * 2 })
        console.log("rect.height = " + rect.height) // 打印 200, 而非 400
    }
}

可以看出,this 指向的是接收 Qt.binding() 的返回值的对象。在这里,可以理解为 rect 表示的对象。

注意: this 的值不是在属性绑定之外定义的。

展开阅读全文
©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值