QML 語言基礎


新建空的 Qt Quick 項目 helloqml,下面更改一下自動生成的 main.qml 文件:

// 下面是導入語句
import QtQuick 2.9
import QtQuick.Window 2.2

/* QML文檔可以看做是一個QML對象樹,這里創建了Window根對象
和它的子對象Text */
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Text {
        id: text1
        text: qsTr("hello QML!")
    }
}

運行結果如下圖所示:


一、import 語句

類似於 C++ 中的 include,在 QML 中使用 import 語句導入模塊,模塊中包含了各種 QML 類型。QtQuick 模塊為創建圖形用戶界面提供了最基本的類型,比如代碼中使用的 Text 類型就包含在 QtQuick 模塊中,QML文檔中首先要導入該模塊。這里我們導入了 QtQuick 2.9。

因為代碼中使用了 Window 類型,所以這里還導入了 QtQuick.Window 模塊。Window類型可以為 Qt Quick 場景創建一個頂級窗口,所以它一般作為根對象,在其中可以創建其他 QML 對象。


二、QML類型

QML 的類型系統包含了基本類型、 QML 對象類型和 JavaScript 類型,這些類型組成了整個 QML 文檔。

  • 基本類型

    在 QML 中將指向簡單數據的類型稱為基本類型,比如 int 或 string 等。基本類型的概念是相對於 QML 對象類型而言的,QML 對象類型可以包含屬性、信號和函數等,但基本類型不能作為對象,比如 int {} 是不允許的。

  • **QML 對象類型 **

    QML 對象類型就是可以實例化 QML 對象的類型。從語法上面來說,QML 對象類型可以通過類型名稱{對象特性} 的格式來定義一個對象。例如,代碼中 Window 和 Text 都是對象類型。當對象類型被實例化以后,就被叫做該對象類型的對象 ,例如 Text 對象類型在代碼中被實例化為了 Text 類型的對象 Text,之所以這兩個概念容易被混淆,是因為它們是同名的。只需要記住對象類型后面添加 {} 后就被稱為對象 ,大家也可以類比C++中的類與實例化。

  • **JavaScript 類型 **

    QML 支持 JavaScript 對象和數組,可以通過var 類型創建並存儲任何標准的 JavaScript 類型。


三、對象

在前面對象類型處已經講明了什么是對象,這里再重申一下。QML 對象由類型指定,一般與類型同名,名稱以大寫字母開頭,后面跟一對大括號,在括號中包含了對象特性定義,包括 id、屬性、信號、信號處理器、方法、附加屬性和附加信號處理器等,當然也可以包含子對象。例如,前面代碼中 Window 對象中包含了 visible、width、height、title 等屬性定義和 Text 子對象。


四、屬性

屬性是對象的特性之一,可以分配一個靜態的值或者綁定一個動態表達式,屬性和值由一個冒號隔開,使用 “屬性 : 值” 語法進行初始化,比如前面代碼中width: 640 。屬性可以分行寫,這樣結尾可以不用分號,也可以寫在一行,中間使用分號隔開,例如:width: 640; height: 480 。可以在任意對象類型的幫助文檔中查看該類型的所有屬性。


4.1 屬性的類型

可以在 QML 文檔中使用的類型大概有三類:

  • 由 QML 語言本身提供的基本類型。
  • 由 QML 模塊(比如 Qt Quick)提供的類型。
  • 導出到 QML 環境中的 C++ 類型。

(1)基本類型

QML 支持的基本類型包括 int、real、double、bool、string、color、List、font 等。這些基本類型有些是和 ECMAScript 語言的基本類型對應的,比如 string。

還是之前的示例,修改了一下,通過注釋標注了屬性類型:

Window {
    visible: true // bool
    width: 640 // int
    height: 480 // int
    title: qsTr("Hello World") // string

    Text {
        id: text1
        text: qsTr("hello QML!")  // string
        z: 1.5 // real
    }
}

可以使用 Qt 幫助的索引模式,以 "qml base types" 為關鍵字檢索,找到 QML Basic Types 頁面來查看完整的類型列表和每種類型的詳情。

注意,QML 中對象的屬性是有類型安全檢測的,也就是說,你只能指定與屬性類型匹配的值,否則會報錯。


(2)id 屬性

每一個對象都可以指定一個唯一的 id 值,這樣便可以在其他對象中識別並引用該對象。例如,下面的代碼中有兩個 Text 對象,第一個 Text 對象的 id 值為 "text1"。現在第二個 Text 對象便可以引用 text1.text 來設置自己的 text 屬性與第一個 Text 對象的 text 屬性具有相同的值:

ROW {
   Text {
       id: text1
       text: "Hello World"
   }
    
    Text { text: text1.text}
}

對於一個 QML 對象而言,id 值是一個特殊的值,不要把它看作一個普通的對象屬性。 例如前面代碼中Text 對象的 id 為 text1,所以可以在其他對象中通過 text1.text 來獲取 Text 對象中的 text 屬性的值, 但無法通過text1.id 來獲取 id 的值。

注意:id 值必須使用小寫字母或者下划線開頭,並且不能使用字母、數字和下划線以外的字符,其值在一個組件的作用域中必須是唯一的。


4.2 屬性更改通知

當一個屬性更改值時,它會發送一個信號來告知這個更改。要獲取這個信號,只需要創建一個信號處理器(signal handler),它使用 "on<Property>Changed" 語法來命名。示例程序如下:

Rectangle {
    width: 640; height:480
    onWidthChanged: console.debug("Width has changed to:", width)
    onHeightChanged: console.debug("height has changed to:", width)    
}

Rectangle 元素擁有 width 和 height 屬性,且定義了兩個信號處理器,無論何時屬性被修改了,都會自動調用它們。


4.3 列表屬性

列表是包括在方括號內,以逗號分隔的多個元素的集合。示例如下:

Item {
    children: [
        Image {},
        Text {}
    ]
}

如果列表中只有一個元素,那么可以省略掉方括號:

Item {
    children: Text {}
}

其實列表和 ESMAScript 的數組(Array)是類似的,其訪問方式也一樣:

  • 可以用 [value1, value2, ..., valueN] 這種形式給 list 對象賦值。
  • length 屬性提供了列表內元素的個數。
  • 列表內的元素通過數組下標來訪。

訪問列表的示例程序如下:

Item {
	children:{
		Text {
			text: "textOne"		
		}
		Text {
			text: "textTwo"		
		}	
	}
	
	Component.onCompleted: {
		for (vat i=0; i<children.length; i++)
			console.log("text of label", i, ":", children[i].text)
	}
		
}

4.4 分組屬性

在某些情況下使用一個 "." 符號或分組符號將相關的屬性形成一個邏輯組。有時我們給分組屬性賦值是一個個來的,類似於這樣:

Text {
    font.pixelSize: 18
    font.bold: true
}

其實下面這樣的寫法在形式上更貼合分組的含義:

Text {
    font { pixelSize: 18; bold: true; }
}

其實可以這么理解,font 屬性的類型本身是一個對象,這個對象又有 pixelSize、bold、italic、underline 等屬性。對於類型為對象的屬性值,可以使用 "." 操作符展開對象的每一個成員對其賦值,也可以通過分組符號(一對花括號)把要賦值的成員放在一起給它們賦值。


4.5 附加屬性

在 QML 語言的語法中,有一個附加屬性的概念,這是附加到一個對象上的額外的屬性。

舉個例子,下面的 Item 對象使用了附加屬性:

import QtQuick 2.2

Item {
    width: 100
    height: 100
    
    focus: true
    keys.enabled: false
}

你看,Item 對象設置 keys.enabled 為false,Keys 就是 Qt Quick 提供的供 Item 處理按鍵事件的附加屬性。與附加屬性相似的概念還有附加信號處理器,我們后面再講。


參考:

《Qt Quick 核心編程》第3章 QML語言基礎



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM