1. 類型名稱必須以大寫字母開頭
導入語法
一個QML文檔可以在文件頂部具有一個或多個導入。導入可以是以下任意一項:
- 已註冊類型的版本化名稱空間(例如,通過插件)
- 在相對目錄中包含qml類型定義的文件
- 一個JavaScript文件
各種import的通用形式如下:
import Namespace VersionMajor.VersionMinor
import Namespace VersionMajor.VersionMinor as SingletonTypeIdentifier
import "directory"
import "file.js" as ScriptIdentifier
例子:
import QtQuick 2.0
import QtQuick.LocalStorage 2.0 as Database
import "../privateComponents"
import "somefile.js" as Script
QML對象屬性
QML對象類型屬性類型集如下:
- the id attribute
- property attributes
- signal attributes
- signal handler attributes
- method attributes
- attached properties and attached signal handler attributes
- enumeration attributes
ID屬性(特殊屬性)
每種QML對象類型都只有一個id屬性。此屬性由語言本身提供,
id值
必須以小寫字母或下劃線開頭,並且不能包含字母,數字和下劃線以外的字符。
id必須唯一
id定義後不能通過屬性賦值進行修改
import QtQuick 2.0
Column {
width: 200; height: 200
TextInput { id: myTextInput; text: "Hello World" }
Text { text: myTextInput.text }
}
屬性的特性
一個屬性的值可以被其他對象讀取。通常,它也可以由另一個對象修改,除非特定的QML類型明確禁止特定屬性使用。、
定義屬性的特性
在C++中使用Q_PROPERTY進行定義後,會註冊到QML類型系統中,還可以在QML文檔中使用
[default] property <propertyType> <propertyName>
進行註冊。這樣,就可以屬性值暴露給外部對象。
屬性名稱必須以小寫字母開頭,並且只能包含字母,數字和下劃線。JavaScript保留字不是有效的屬性名稱。
聲明自定義屬性會隱式創建該屬性的值更改信號以及名爲on <PropertyName> Changed的關聯信號處理程序,其中<PropertyName>是屬性的名稱,首字母大寫。
Rectangle {
property color previousColor
property color nextColor
onNextColorChanged: console.log("The next color will be: " + nextColor.toString())
}
Item {
property int someNumber
property string someString
property url someUrl
}
QtQuick
模塊提供了一些基本類型,因此除非導入模塊,否則不能用作屬性類型。
var基本類型是通用佔位符類型,可以保存任何類型的值,包括列表和對象:
property var someNumber: 1.5
property var someString: "abc"
property var someBool: true
property var someList: [1, 2, "three", "four"]
property var someObject: Rectangle { width: 100; height: 100; color: "red" }
此外,任何QML對象類型(包括自定義類型)都可以用作屬性類型。例如
property Item someItem
property Rectangle someRectangle
屬性賦值
可以通過兩種方式指定對象實例的屬性值
- a value assignment on initialization (初始化)
- an imperative value assignment (命令行賦值)
初始化賦值方法
<propertyName> : <value>
定義屬性時順帶賦值
[default] property <propertyType> <propertyName> : <value>
賦值示例
import QtQuick 2.0
Rectangle {
color: "red"
property color nextColor: "blue" // combined property declaration and initialization
}
命令行賦值,是使用javascript中進行賦值
[<objectId>.]<propertyName> = value
示例
import QtQuick 2.0
Rectangle {
id: rect
Component.onCompleted: {
rect.color = "red"
}
}
類型安全
屬性是類型安全的。只能爲屬性分配與屬性類型匹配的值
特殊屬性類型
Object List Property Attributes
列表類型定義
[ <item 1>, <item 2>, ... ]
例:
import QtQuick 2.0
Item {
states: [
State { name: "loading" },
State { name: "running" },
State { name: "stopped" }
]
}
如果列表中只有一項,可以省略方括號
import QtQuick 2.0
Item {
states: State { name: "running" }
}
列表屬性聲明語法:
[default] property list<<objectType>> propertyName
聲明加初始化語法
[default] property list<<objectType>> propertyName: <value>
例子
import QtQuick 2.0
Rectangle {
// declaration without initialization
property list<Rectangle> siblingRects
// declaration with initialization
property list<Rectangle> childRects: [
Rectangle { color: "red" },
Rectangle { color: "blue"}
]
}
如果聲明一個值不是QML對象,需要使用var定義
分組屬性
在某些情況下,屬性包含一組邏輯的子屬性屬性。可以使用點符號(.)或組符號({})將這些子屬性屬性分配給它們。
例
Text {
//dot notation
font.pixelSize: 12
font.b: true
}
Text {
//group notation
font { pixelSize: 12; b: true }
}
屬性別名
屬性別名語法
[default] property alias <name>: <alias reference>
命名用限制:
1.只能引用在同一作用域的對象或對象屬性
2.不能包含Js表達式
3.屬性別名必須初始化
4.不能引用附加屬性
5.不能引用深度爲3或更大的層次結構內的屬性
例
property alias color: myItem.myRect.border.color //超過3層,不能使用
Item {
id: myItem
property Rectangle myRect
}
property alias color: rectangle.border.color //命名用兩級是可以的
Rectangle {
id: rectangle
}
例
// Button.qml
import QtQuick 2.0
Rectangle {
property alias buttonText: textItem.text //按鈕就可以直接操作文本了
width: 100; height: 30; color: "yellow"
Text { id: textItem }
}
使用按鈕如下:
Button { buttonText: "Click Me" }
屬性別名注意事項
僅在組件完全初始化後才能激活別名
別名屬性可能與現有屬性具有相同的名稱,從而有效覆蓋現有屬性。
例:
Rectangle {
id: coloredrectangle
property alias color: bluerectangle.color
color: "red"
Rectangle {
id: bluerectangle
color: "#1234ff"
}
Component.onCompleted: {
console.log (coloredrectangle.color) //prints "#1234ff"
setInternalColor()
console.log (coloredrectangle.color) //prints "#111111"
coloredrectangle.color = "#884646"
console.log (coloredrectangle.color) //prints #884646
}
//internal function that has access to internal properties
function setInternalColor() {
color = "#111111"
}
}
屬性別名沒有明確的類型,如果將爲一個對象的ID指定別明,是不能使用別名掉用對象屬性的
例
// MyItem.qml
Item {
property alias inner: innerItem
Item {
id: innerItem
property int extraProperty
}
}
// main.qml
MyItem {
inner.extraProperty: 5 // fails
}
如果別名組件是一個單獨文件定義的對象的話,是可以使用別名訪問屬性的
// MainItem.qml
Item {
// Now you can access inner.extraProperty, as inner is now an ExtraItem
property alias inner: innerItem
ExtraItem {
id: innerItem
}
}
// ExtraItem.qml
Item {
property int extraProperty
}
默認屬性
定義默認屬性的語法
default property var someText
默認屬性每個對象只能定義一個
默認對象不用再通過屬性名進行賦值
// MyLabel.qml
import QtQuick 2.0
MyLabel {
default property var someText
text: "Hello, " + someText.text
}
//調用時沒有使用someText:Text { text: "world!" },默認屬性可省略someText:
MyLabel {
Text{ text: "world!" }
}
只讀屬性
只讀屬性語法:
readonly property <propertyType> <propertyName> : <initialValue>
初始化時必須爲只讀屬性分配一個值。以後再也不能以任何方式進行賦值。
屬性修改器對象
屬性可以有屬性值修改器對象和他們關聯。聲明關聯到具體屬性的修改器類型實例的語法如下:
<PropertyModifierTypeName> on <propertyName> {
// attributes of the object instance
}
信號屬性
信號處理程序使用 on<Signal> 語法聲明, <Signal> 是信號名,第一個字母大寫。信號處理程序必須聲明在觸發該信號的對象的定義內,並且處理程序應該包含 JavaScript 代碼塊當信號處理程序被調用時執行。
import QtQuick 2.0
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Click!")
}
}
}
定義信號屬性
signal <signalName>[([<type> <parameter name>[, ...]])]
import QtQuick 2.0
Item {
signal clicked
signal hovered()
signal actionPerformed(string action, var actionResult)
}
觸發信號,像調用方法一樣調用信號。信號被觸發時任何信號相關的處理將被調用,處理程序可以使用信號已定義的參數訪問各自的參數。
信號處理程序屬性
// SquareButton.qml
Rectangle {
id: root
signal activated(real xPosition, real yPosition) //定義信號
signal deactivated //定義信號
property int side: 100
width: side; height: side
MouseArea {
anchors.fill: parent
onPressed: root.activated(mouse.x, mouse.y) //發送信號
onReleased: root.deactivated() //發送信號
}
}
// myapplication.qml //同一文件夾下接收信號並處理。
SquareButton {
onActivated: console.log("Activated at " + xPosition + "," + yPosition)
onDeactivated: console.log("Deactivated!")
}
屬性改變信號的處理
屬性改變的信號的處理程序使用語法 on<Property>Changed ,<Property> 是屬性的名字並且第一個字母大寫。
import QtQuick 2.0
TextInput {
text: "Change this!"
onTextChanged: console.log("Text has changed to:", text)
}
方法屬性
對象類型的方法是一個可以被調用去執行一些處理或觸發後續事件的函數。方法可以連接到信號以便信號被觸發時它可以被自動調用。
定義方法屬性
類型的方法定義,可以在C++中使用 Q_INVOKABLE 標註將被註冊到QML類型系統的類的函數,或者註冊該函數爲類的 Q_SLOT 。使用如下的語法在QML文檔內添加自定義方法到對象的聲明:
function <functionName>([<parameterName>[, ...]]) { <body> }
方法定義:
import QtQuick 2.0
Rectangle {
id: rect
function calculateHeight() {
return rect.width / 2;
}
width: 100
height: calculateHeight()
}
方法使用:
import QtQuick 2.0
Item {
width: 200; height: 200
MouseArea {
anchors.fill: parent
onClicked: label.moveTo(mouse.x, mouse.y)
}
Text {
id: label
function moveTo(newX, newY) {
label.x = newX;
label.y = newY;
}
text: "Move me!"
}
}
附加屬性和附加信號處理程序
附加屬性和附加信號處理程序是一種使對象被解釋爲擴展屬性或信號處理程序(否則無效)的機制,特別地,這允許對象訪問與個別對象明確相關的屬性或者信號。
語法:
<AttachingType>.<propertyName>
<AttachingType>.on<SignalName>
示例
/*比如, ListView 類型有一個可被附加的屬性 ListView.isCurrentItem 並且 ListView 內的每一個代理對象可使用(此附加屬性)。這可以被每一個不同的代理對象用來確定自己是否是視圖內當前被選中的元素。*/
import QtQuick 2.0
ListView {
width: 240; height: 320
model: 3
delegate: Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow"
}
}
訪問附加屬性和信號處理程序的注意事項
附加類型的實例僅僅附屬於特定對象,不屬於對象和它的所有子對象。
import QtQuick 2.0
ListView {
width: 240; height: 320
model: 3
delegate: Item {
width: 100; height: 30
Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow" // WRONG! This won't work.
}
}
}
//以下是正確寫法
ListView {
//....
delegate: Item {
id: delegateItem
width: 100; height: 30
Rectangle {
width: 100; height: 30
color: delegateItem.ListView.isCurrentItem ? "red" : "yellow" // correct
}
}
}
枚舉屬性
// MyText.qml
Text {
enum TextType {
Normal,
Heading
}
}
// MyText.qml
Text {
enum TextType {
Normal,
Heading
}
property int textType: MyText.TextType.Normal
font.bold: textType == MyText.TextType.Heading
font.pixelSize: textType == MyText.TextType.Heading ? 24 : 12
}
枚舉屬性只能在5.10以後使用