一起來學 QML & Qt 5 (II) - QML語法

QML語法

  • QML是一種描述使用者介面的標記語言
  • 使用者介面上看到的東西,是由很多元素跟組件所組成。一些元素能夠結合起來成為一個組件
  • JavaScript可以用來修飾(或修改)使用者介面
  • 元素具有層次結構
    • 我覺得看起來的感覺很像 JavaScript 裡面的 literral object,因此我對於QML語法第一眼的感覺很親切,所以我就把它想像成那一回事,蠻好理解的
    • 層次結構就好像是「物件(元素)中還有物件(元素),然後物件(元素)中還有物件(元素) .... 」
    • 既然這麼有層次,那麼一定會有一個老大,是這些元素的老祖宗
    • 子元素的 (x, y) 座標是相對於它的父座標系統。意思就是說,每個元素的(x, y)是由父元素的座標系統所定義的。我這樣理解:「我坐落在我父元素的哪個位置」

// rectangle.qml

import QtQuick 2.0  // 導入module

// The root element is the Rectangle (Rectangle就是此元素的類型, {} 中是它的內容)
Rectangle {
    // name this element root
    // 每個QML文件都需要一個根元素,就像HTML一樣
    // 根元素的名字不一定要取名叫root,但取root在語義上就很清楚
    // id是識別字,可以根據id來訪問它。在QML的其他地方,可透過id來引用該元素
    // id在QML中是唯一的,並且在設定後不能被修改為其他值,也無法被查詢
    id: root

    // 元素屬性(properties)的格式是鍵值對: : 
    width: 120; height: 240

    // color property
    color: "#D8D8D8"

    // Declare a nested element (child of root)
    Image {
        id: rocket

        // 子元素可以通過parent關鍵字來訪問它的父元素
        // x屬性依賴於parent的width屬性,術語稱為屬性綁定
        x: (parent.width - width)/2; y: 40

        source: 'assets/rocket.png'
    }

    // Another child of root
    Text {
        // un-named element

        // reference element by id
        y: rocket.y + rocket.height + 20

        // reference root element
        width: root.width

        horizontalAlignment: Text.AlignHCenter
        text: 'Rocket'
    }
}

屬性

  • 鍵值對
  • 元素在宣告其「類型」後,由「屬性們」所定義
  • 一個元素類型,有預設的屬性。你也可以用 property 關鍵字來自定義屬性,自定義屬性時,要同時宣告屬性的資料型別(例如 int)。使用 property alias 可以為某個屬性名稱取一個綽號(別名)
  • 屬性也可以用組歸類,其實也是像一個物件的樣子
    • 例如 font{family: "UBuntu"; pixelSize: 24 } 
  • 對每個元素都可以提供訊號操作,這個操作在元素的屬性值改變時被調用。我是把它看成「屬性改變時」的 callback (就好像 listener 的 handler 一樣)
    • 格式: on屬性名Changed
    • 例如 onHeightChanged
以下是原文提供的範例,讀一下應該很好懂
    Text {
        // (1) identifier
        id: thisLabel

        // (2) set x- and y-position
        x: 24; y: 16

        // (3) bind height to 2 * width
        height: 2 * width

        // (4) custom property
        property int times: 24

        // (5) property alias
        property alias anotherTimes: thisLabel.times

        // (6) set text appended by value
        text: "Greetings " + times

        // (7) font is a grouped property
        font.family: "Ubuntu"
        font.pixelSize: 24

        // (8) KeyNavigation is an attached property
        KeyNavigation.tab: otherLabel

        // (9) signal handler for property changes
        onHeightChanged: console.log('height:', height)

        // focus is neeed to receive key events
        focus: true

        // change color based on focus value
        color: focus?"red":"black"
    }

腳本

  • 就是 onXXX handler 的內容,可用scripting的方式描述
  • 要在QML裡面寫一個 JavaScript 的 function 也是可以的,這個 funciton 可在 QML 中被調用
還是一樣,看一下原文程式碼,就可以普普了解啦....

    Text {
        id: label

        x: 24; y: 24

        // custom counter property for space presses
        property int spacePresses: 0

        text: "Space pressed: " + spacePresses + " times"

        // (1) handler for text changes
        onTextChanged: console.log("text changed to:", text)

        // need focus to receive key events
        focus: true

        // (2) handler with some JS
        Keys.onSpacePressed: {
            increment()
        }

        // clear the text on escape
        Keys.onEscapePressed: {
            label.text = ''
        }

        // (3) a JS function
        function increment() {
            spacePresses = spacePresses + 1
        }
    }

沒有留言

技術提供:Blogger.