QML對象類型屬性類型集如下:
- id 屬性
- 普通屬性
- 信號屬性
- 信號處理程序屬性
- 方法屬性
- 附加屬性和附加信號處理程序屬性
這些屬性將在下面詳細討論.
id 屬性
每種QML對象類型都只有一個屬性. 此屬性由語言本身提供,並且不能由任何QML對象類型重新定義或覆蓋.
可以將值分配給對象實例的屬性,以允許該對象被其他對象標識和引用. 此id
必須以小寫字母或下劃線開頭,並且不能包含字母,數字和下劃線以外的字符.
下面是一個TextInput對象和一個Text對象. TextInput對象的id
值設置爲" myTextInput". 通過引用myTextInput.text
, Text對象將其text
屬性設置爲與TextInput的text
屬性具有相同的值. 現在,兩個項目將顯示相同的文本:
import QtQuick 2.0
Column {
width: 200; height: 200
TextInput { id: myTextInput; text: "Hello World" }
Text { text: myTextInput.text }
}
可以在聲明對象的內的任何位置通過其id
引用對象. 因此, id
值在其組件範圍內必須始終是唯一的.
創建對象實例後,無法更改其屬性的值. 雖然它可能看起來像一個普通的屬性,id
屬性不是一個普通的property
屬性; 例如,在上面的示例中無法訪問myTextInput.id
Property Attributes (普通屬性)
屬性是可以分配靜態值或綁定到動態表達式的對象的屬性. 一個屬性的值可以被其他對象讀取. 通常,它也可以由另一個對象修改,除非特定的QML類型明確禁止特定屬性使用.
通過註冊類的Q_PROPERTY ,然後再向QML類型系統註冊,可以在C ++中爲類型定義屬性. 或者,可以使用以下語法在QML文檔的對象聲明中定義對象類型的自定義屬性:
Rectangle {
property color previousColor
property color nextColor
onNextColorChanged: console.log("The next color will be: " + nextColor.toString())
}
屬性名稱必須以小寫字母開頭,並且只能包含字母,數字和下劃線. JavaScript保留字不是有效的屬性名稱.
除了枚舉類型外,任何QML基本類型都可以用作自定義屬性類型,例如
Item {
property int someNumber
property string someString
property url someUrl
}
此外,任何QML對象類型都可以用作屬性類型. 例如:
property Item someItem
property Rectangle someRectangle
爲屬性屬性賦值
可以通過兩種不同的方式指定對象實例的屬性值:
- 初始化時
- 需要的時候賦值
在初始化時爲屬性分配值的語法是:
<propertyName> : <value>
如果需要,可以將初始化值分配與對象聲明中的屬性定義組合. 在這種情況下,屬性定義的語法變爲:
property <propertyType> <propertyName> : <value>
屬性值初始化的示例如下:
import QtQuick 2.0
Rectangle {
color: "red"
property color nextColor: "blue" // combined property declaration and initialization
}
需要的時候賦值
import QtQuick 2.0
Rectangle {
id: rect
Component.onCompleted: {
rect.color = "red"
}
}
以下示例,顯示了兩種方法給屬性賦值:
import QtQuick 2.0
Rectangle {
// both of these are static value assignments on initialization
width: 400
height: 200
Rectangle {
// both of these are binding expression value assignments on initialization
width: parent.width / 2
height: parent.height
}
}
屬性安全問題
就像c++一樣,int 類型不能賦值string,QML裏也一樣只能爲屬性分配與屬性類型匹配的值
例如,如果一個屬性是一個實數,並且如果您嘗試爲其分配一個字符串,則會出現錯誤:
property int volume: "four" // generates an error; the property's object will not be loaded
同樣,如果在運行時爲屬性分配了錯誤類型的值,則不會分配新值,並且會生成錯誤.
可以爲列表類型屬性分配QML對象類型值的列表. 定義對象列表值的語法是用方括號括起來的逗號分隔列表:
例如, Item類型具有一個states屬性,該屬性用於保存State類型對象的列表. 下面的代碼將該屬性的值初始化爲三個State對象的列表:
import QtQuick 2.0
Item {
states: [
State { name: "loading" },
State { name: "running" },
State { name: "stopped" }
]
}
如果列表包含單個項目,則可以省略方括號:
import QtQuick 2.0
Item {
states: State { name: "running" }
}
可以使用以下語法在對象聲明中指定列表類型屬性:
property list<<objectType>> propertyName
//或者
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屬性.
Signal Attributes 信號屬性
信號是來自某個對象的通知,表明發生了某些事件:例如,屬性已更改,動畫已開始或停止或下載圖像時. 例如, MouseArea類型具有單擊信號,當用戶在鼠標區域內單擊時發出該信號.
每當發出特定信號時,可以通過信號處理程序通知對象. where is the name of the signal, with the first letter capitalized. 使用語法聲明信號處理程序,其中是名稱,首字母大寫. 必須在發出信號的對象的定義內聲明信號處理程序,並且該處理程序應包含在調用信號處理程序時要執行的JavaScript代碼塊.
例如,下面的信號處理程序在MouseArea對象定義中聲明,並在單擊MouseArea時被調用,從而導致控制檯消息被打印:
import QtQuick 2.0
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Click!")
}
}
}
通過註冊一個類的Q_SIGNAL ,然後在QML類型系統中註冊,可以爲C ++中的類型定義一個信號. 或者,可以使用以下語法在QML文檔的對象聲明中定義對象類型的自定義信號:
signal <signalName>[([<type> <parameter name>[, ...]])]
試圖在同一類型塊中聲明兩個具有相同名稱的信號或方法是錯誤的. 但是,新信號可能會在類型上重複使用現有信號的名稱. (這應該謹慎行事,因爲現有信號可能會被隱藏並變得難以訪問.)
這是信號聲明的三個示例:
import QtQuick 2.0
Item {
signal clicked
signal hovered()
signal actionPerformed(string action, var actionResult)
}
如果信號沒有參數,則"()"括號是可選的. 如果使用了參數,則必須聲明參數類型,就像上述actionPerformed
信號的string
和var
參數一樣. 允許的參數類型與此頁面上的" 定義屬性屬性"下列出的參數類型相同.
要發出信號,請將其作爲方法調用. 發出信號時,將調用任何相關的信號處理程序 ,並且處理程序可以使用定義的信號參數名稱來訪問相應的參數.
屬性改變信號
QML類型還提供了內置的 ,每當屬性值更改時都會發出該 ,如先前在屬性屬性部分中所述. QML屬性的值更改時,會自動發出信號.格式是on<Signal> 這種形式。
import QtQuick 2.0
Rectangle {
id: rect
width: 100; height: 100
MouseArea {
anchors.fill: parent
onPressedChanged: {
console.log("Mouse area is pressed?", pressed)
}
}
}
在上面示例中MouseArea觸發pressedChanged信號。我們捕捉這個信號就用onPressedChanged就可以了 ,沒錯,首部加on,信號首字母變爲大寫就可以了!
即使MouseArea文檔沒有記錄名爲onPressedChanged
的信號處理程序,該信號onPressedChanged
被pressed
屬性存在的事實隱式提供.
Using the Connections Type
在某些情況下,可能希望訪問發出該信號的對象之外的信號. 爲此, QtQuick
模塊提供了Connections類型,用於連接到任意對象的信號. Connections對象可以從其指定的目標接收任何信號.
例如, onClicked
在前面的示例中的處理程序可能已被由所述根接收矩形代替,通過將onClicked
處理程序在一個連接對象,該對象具有其目標設定到鼠標區域 :
import QtQuick 2.0
Rectangle {
id: rect
width: 100; height: 100
MouseArea {
id: mouseArea
anchors.fill: parent
}
Connections {
target: mouseArea
onClicked: {
rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
}
}
}
簡單的介紹下qml信號,會具體一章來講qml的信號和槽,並且會有詳細的示例代碼。還有c++與qml的信號傳遞與一些好用的技巧分享。
Attributes 方法屬性
可以通過在C ++中爲類型定義一種方法,方法是標記一個類的功能,然後用Q_INVOKABLE在QML類型系統中註冊該類,或者將其註冊爲該類的Q_SLOT . 或者,可以使用以下語法將自定義方法添加到QML文檔中的對象聲明中:
function <functionName>([<parameterName>[, ...]]) { <body> }
可以將方法添加到QML類型,以定義獨立的可重用的JavaScript代碼塊. 這些方法可以在內部或外部對象中調用.
與信號不同,方法參數類型不必聲明,因爲它們默認爲var
類型.
下面是一個帶有calculateHeight()
方法的矩形 ,該矩形在分配height
值時被調用:
import QtQuick 2.0
Rectangle {
id: rect
function calculateHeight() {
return rect.width / 2;
}
width: 100
height: calculateHeight()
}
如果該方法具有參數,則可以在方法內按名稱訪問它們. 在下面,當單擊MouseArea時,它將調用moveTo()
方法,該方法然後可以引用接收到的newX
和newY
參數來重新newY
文本:
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!"
}
}