1. 程式人生 > 其它 >QML 中的屬性繫結

QML 中的屬性繫結

技術標籤:QMLqml

QML 中的屬性繫結

有兩種方法可以給 QML 物件的屬性進行賦值:靜態值和繫結值。

例如 height: 100,這是一個靜態值。然而 height: width * 2,這就是一個繫結值。繫結值表示屬性的值跟將隨繫結表示式計算出來的值。這裡表示的是高永遠是寬的兩倍。

運用繫結表示式給物件賦值也就是常說的屬性繫結(Property Binding),它是 QML 中的一個核心特性。

一、使用冒號

以冒號表示的屬性繫結是最常見的屬性繫結方法。冒號後面的可以是任意 JS 表示式或者語句、QML 物件屬性、函式呼叫以及 JS 中的內建物件,比如 Date、Math 等。

// 動態繫結示例
height: parent.height / 2

height: Math.min(parent.width, parent.height)

height: parent.height > 100 ? parent.height : parent.height / 2

height: {
    if (parent.height > 100)
        return parent.height
    else
        return parent.height / 2
}

height: someMethodThatReturnsHeight()

以上的屬性繫結方式,如果在 JS 語句中再次指定了一個靜態值,繫結將從此失效。

Rectangle {
    width: 100
    height: width * 2

    focus: true
    Keys.onSpacePressed: {
        height = width * 3 // 按下空格鍵後,height 的值將不再隨 width 的變化而變化
    }
}

但可以重新繫結,方法是使用 Qt.binding(function)

二、Qt.binding(function) 方法

Rectangle {
    width: 100
    height: width * 2

    focus: true
    Keys.onSpacePressed:
{ height = Qt.binding(function() { return width * 3 }) // 重新繫結 } }

在 JS 函式中進行屬性繫結時,還可以使用 this 關鍵字,它代表接收這個繫結的物件。

Item {
    width: 500
    height: 500
    Rectangle {
        id: rect
        width: 100
        color: "yellow"
    }
    Component.onCompleted: {
        rect.height = Qt.binding(function() { return this.width * 2 }) // this 代表的是 rect
        console.log("rect.height = " + rect.height) // prints 200, not 1000
    }
}

另外一種屬性繫結的繫結方法是:運用 QML 中的 Binding 型別。

三、Binding 型別

Binding 主要提供兩種能力:

  1. 繫結到不可訪問的屬性

    // app 是 C++ 中匯出的屬性,在 QML 中不可直接進行屬性繫結,但可用 Binding 進行繫結
    TextEdit { id: myTextField; text: "Please type here..." }
    Binding { target: app; property: "enteredText"; value: myTextField.text }
    
  2. 條件繫結

    Binding 可以通過 delay 設定延時繫結:不會立即更新被繫結的物件,要等到事件佇列空閒的時候再去響應。

    Binding 可以通過 when 指定何種條件下才去響應。

總結

QML 中的屬性繫結有三種方法:

  1. QML 物件初始化時用冒號繫結

    能在物件初始化時繫結,不能在執行時繫結

  2. 執行時在 JS 函式中用 Qt.binding() 方法繫結

    不能在初始化時繫結,能在執行時繫結

  3. Binding 型別進行繫結

    能給不可訪問的屬性進行繫結,可以設定條件繫結

參考

https://doc.qt.io/qt-5/qtqml-syntax-objectattributes.html

https://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html

https://doc.qt.io/qt-5/qml-qtqml-binding.html

https://zhuanlan.zhihu.com/p/56401271