QML對象屬性
每個(gè)QML對象類型都有一組定義的屬性司浪。使用為該對象類型定義的屬性集創(chuàng)建對象類型的每個(gè)實(shí)例微饥∷熳可以指定幾種不同的屬性头岔,如下所述塔拳。
對象聲明中的屬性
QML文檔中的對象聲明(object declaration)定義了一種新類型。它還聲明了一個(gè)對象層次結(jié)構(gòu)峡竣,如果創(chuàng)建該新定義類型的實(shí)例蝙斜,則將實(shí)例化該對象層次結(jié)構(gòu)。
QML對象類型屬性類型的集合如下:
- ID屬性
- 屬性屬性
- 信號屬性
- 信號處理程序?qū)傩?/li>
- 方法屬性
- 附加屬性和附加信號處理程序?qū)傩?/li>
- 枚舉屬性
這些屬性將在下面詳細(xì)討論澎胡。
ID屬性
每個(gè)QML對象類型都有一個(gè)唯一的id屬性孕荠。此屬性由語言本身提供娩鹉,并且不能由任何QML對象類型重新定義或覆蓋。
可以將值分配給對象實(shí)例的id屬性稚伍,以允許該對象被其他對象標(biāo)識和引用弯予。它id
必須以小寫字母或下劃線開頭,并且不能包含字母个曙,數(shù)字和下劃線以外的字符锈嫩。
import QtQuick 2.0
Column {
width: 200; height: 200
TextInput { id: myTextInput; text: "Hello World" }
Text { text: myTextInput.text }
}
可以在聲明對象id
的組件范圍內(nèi)的任何位置引用該對象。因此垦搬,id
值在其組成范圍內(nèi)必須始終是唯一的呼寸。有關(guān)更多信息,請參見作用域和命名分辨率猴贰。
創(chuàng)建對象實(shí)例后对雪,無法更改其id屬性的值。盡管它看起來像是普通屬性米绕,但該id
屬性不是普通property
屬性瑟捣,并且特殊語義適用于此屬性;例如栅干,myTextInput.id
在上面的示例中無法訪問迈套。
屬性Property
屬性是可以分配靜態(tài)值或綁定到動態(tài)表達(dá)式的對象的屬性。一個(gè)屬性的值可以被其他對象讀取碱鳞。通常桑李,它也可以由另一個(gè)對象修改,除非特定的QML類型明確禁止特定屬性使用窿给。
定義Property屬性
通過注冊類的Q_PROPERTY贵白,然后再向QML類型系統(tǒng)注冊,可以在C ++中為類型定義屬性填大。或者俏橘,可以使用以下語法在QML文檔的對象聲明中定義對象類型的自定義屬性:
[default] property <propertyType> <propertyName>
這樣允华,對象聲明可以將特定的值暴露給外部對象,或者更容易維護(hù)一些內(nèi)部狀態(tài)寥掐。
屬性名稱必須以小寫字母開頭靴寂,并且只能包含字母,數(shù)字和下劃線召耘。JavaScript保留字不是有效的屬性名稱百炬。該default
關(guān)鍵字是可選的,并修改所聲明的屬性的語義污它。有關(guān)屬性修飾符的更多信息剖踊,請參見后面的默認(rèn)屬性部分default
庶弃。
聲明自定義屬性會隱式創(chuàng)建該屬性的值更改信號,以及一個(gè)名為on <PropertyName> Changed的關(guān)聯(lián)信號處理程序德澈,其中<PropertyName>是屬性的名稱歇攻,首字母大寫。
例如梆造,以下對象聲明定義了一個(gè)從Rectangle基本類型派生的新類型缴守。它具有兩個(gè)新屬性,并為這些新屬性之一實(shí)現(xiàn)了信號處理程序:
Rectangle {
property color previousColor
property color nextColor
onNextColorChanged: console.log("The next color will be: " + nextColor.toString())
}
自定義屬性定義中的有效類型
除枚舉類型外镇辉,任何QML基本類型都可用作自定義屬性類型屡穗。例如,這些都是有效的屬性聲明:
Item {
property int someNumber
property string someString
property url someUrl
}
(枚舉值只是整數(shù)值忽肛,可以用int類型來引用村砂。)
QtQuick
模塊提供了一些基本類型,因此除非導(dǎo)入模塊麻裁,否則它們不能用作屬性類型箍镜。有關(guān)更多詳細(xì)信息,請參見QML基本類型文檔煎源。
請注意色迂,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
這也適用于自定義QML類型锋拖。如果在名為ColorfulButton.qml
(在隨后由客戶端導(dǎo)入的目錄中)文件中定義了QML類型诈悍,則type屬性ColorfulButton
也將有效。
將值分配給屬性
可以通過兩種不同的方式指定對象實(shí)例的屬性的值:
- 初始化時(shí)的值分配
- 必要的價(jià)值分配
無論哪種情況兽埃,該值都可以是靜態(tài)值或綁定表達(dá)式值侥钳。
初始化時(shí)的值分配
在初始化時(shí)為屬性分配值的語法是:
<propertyName> : <value>
如果需要,可以將初始化值分配與對象聲明中的屬性定義組合柄错。在這種情況下舷夺,屬性定義的語法變?yōu)椋?/p>
[default] property <propertyType> <propertyName> : <value>
屬性值初始化的示例如下:
import QtQuick 2.0
Rectangle {
color: "red"
property color nextColor: "blue" // combined property declaration and initialization
}
命令性價(jià)值分配
命令性值分配是將屬性值(靜態(tài)值或綁定表達(dá)式)從命令性JavaScript代碼分配給屬性的地方。強(qiáng)制性值賦值的語法只是JavaScript賦值運(yùn)算符售貌,如下所示:
[<objectId>.]<propertyName> = value
強(qiáng)制性值分配的示例如下:
import QtQuick 2.0
Rectangle {
id: rect
Component.onCompleted: {
rect.color = "red"
}
}
靜態(tài)值和綁定表達(dá)式值
如前所述给猾,可以為屬性分配兩種值:靜態(tài)值和綁定表達(dá)式值。后者也稱為屬性綁定颂跨。
類 | 語義學(xué) |
---|---|
靜態(tài)值 | 一個(gè)不依賴于其他屬性的常數(shù)值敢伸。 |
綁定表達(dá) | 一個(gè)JavaScript表達(dá)式,用于描述屬性與其他屬性的關(guān)系恒削。此表達(dá)式中的變量稱為屬性的依賴項(xiàng)池颈。 |
QML引擎強(qiáng)制執(zhí)行屬性及其依賴項(xiàng)之間的關(guān)系尾序。當(dāng)任何依賴項(xiàng)的值發(fā)生變化時(shí),QML引擎都會自動重新計(jì)算綁定表達(dá)式并將新結(jié)果分配給該屬性饶辙。
|
這是一個(gè)示例蹲诀,顯示了兩種分配給屬性的值:
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
}
}
注意:要強(qiáng)制分配綁定表達(dá)式,綁定表達(dá)式必須包含在傳遞給Qt.binding()的函數(shù)中弃揽,然后必須將Qt.binding()返回的值分配給該屬性脯爪。相反,在初始化時(shí)分配綁定表達(dá)式時(shí)矿微,不得使用Qt.binding()痕慢。有關(guān)更多信息,請參見屬性綁定涌矢。
類型安全
屬性是類型安全的掖举。只能為屬性分配與屬性類型匹配的值。
例如娜庇,如果一個(gè)屬性是一個(gè)實(shí)數(shù)塔次,并且如果您嘗試為其分配一個(gè)字符串,則會出現(xiàn)錯(cuò)誤:
property int volume: "four" // generates an error; the property's object will not be loaded
同樣名秀,如果在運(yùn)行時(shí)為屬性分配了錯(cuò)誤類型的值励负,則不會分配新值,并且會生成錯(cuò)誤匕得。
某些屬性類型沒有自然值表示形式继榆,對于這些屬性類型,QML引擎自動執(zhí)行字符串到類型值的轉(zhuǎn)換汁掠。因此略吨,例如,即使color
類型的屬性存儲顏色而不是字符串考阱,您也可以將字符串分配給"red"
color屬性翠忠,而不會報(bào)告錯(cuò)誤。
有關(guān)默認(rèn)支持的屬性類型的列表乞榨,請參見QML基本類型秽之。另外,任何可用的QML對象類型也可以用作屬性類型姜凄。
特殊財(cái)產(chǎn)類型
對象列表屬性屬性
甲列表類型屬性可被分配QML對象類型值的列表政溃。定義對象列表值的語法是用方括號括起來的逗號分隔列表:
[ <item 1>, <item 2>, ... ]
例如趾访,Item類型具有一個(gè)states屬性态秧,該屬性用于保存State類型對象的列表。下面的代碼將該屬性的值初始化為三個(gè)State對象的列表:
import QtQuick 2.0
Item {
states: [
State { name: "loading" },
State { name: "running" },
State { name: "stopped" }
]
}
如果列表包含單個(gè)項(xiàng)目扼鞋,則可以省略方括號:
import QtQuick 2.0
Item {
states: State { name: "running" }
}
列表類型屬性可以與下面的語法的對象聲明中指定:
[default] property list<<objectType>> propertyName
并且申鱼,與其他屬性聲明一樣愤诱,可以使用以下語法將屬性初始化與屬性聲明結(jié)合使用:
[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"}
]
}
如果您希望聲明一個(gè)屬性來存儲值列表,這些列表不一定是QML對象類型的值捐友,則應(yīng)該聲明一個(gè)var屬性淫半。
分組屬性
在某些情況下,屬性包含一組邏輯的子屬性屬性匣砖】瓶裕可以使用點(diǎn)符號或組符號將這些子屬性屬性分配給它們。
例如猴鲫,“ 文本”類型具有字體組屬性对人。下面,第一個(gè)Text對象font
使用點(diǎn)表示法初始化其值拂共,而第二個(gè)對象使用組表示法:
Text {
//dot notation
font.pixelSize: 12
font.b: true
}
Text {
//group notation
font { pixelSize: 12; b: true }
}
分組屬性類型是具有子屬性的基本類型牺弄。這些基本類型中的一些是由QML語言提供的,而其他一些僅在導(dǎo)入Qt Quick模塊時(shí)才可以使用宜狐。有關(guān)更多信息势告,請參見有關(guān)QML基本類型的文檔。
屬性別名(Property Aliases)
屬性別名是保存對另一個(gè)屬性的引用的屬性抚恒。與為屬性分配新的唯一存儲空間的普通屬性定義不同咱台,屬性別名將新聲明的屬性(稱為別名屬性)連接為對現(xiàn)有屬性(別名屬性)的直接引用。
屬性別名聲明看起來像普通的屬性定義柑爸,只是它需要alias
關(guān)鍵字而不是屬性類型吵护,并且屬性聲明的右側(cè)必須是有效的別名引用:
[default] property alias <name>: <alias reference>
與普通屬性不同,別名具有以下限制:
- 它只能引用在聲明別名的類型范圍內(nèi)的對象或?qū)ο蟮膶傩浴?/li>
- 它不能包含任意JavaScript表達(dá)式
- 它不能引用在其類型范圍之外聲明的對象表鳍。
- 該別名引用是不可選的馅而,不像普通的財(cái)產(chǎn)可選默認(rèn)值; 首次聲明別名時(shí),必須提供別名引用譬圣。
- 它不能引用附加屬性瓮恭。
- 它不能引用深度為3或更大的層次結(jié)構(gòu)內(nèi)的屬性。以下代碼不起作用:
property alias color: myItem.myRect.border.color
Item {
id: myItem
property Rectangle myRect
}
但是厘熟,可以使用最多兩層的屬性別名屯蹦。
property alias color: rectangle.border.color
Rectangle {
id: rectangle
}
例如,下面是Button
具有buttonText
別名屬性的類型绳姨,該類型連接到Text子text
對象的對象:
// Button.qml
import QtQuick 2.0
Rectangle {
property alias buttonText: textItem.text
width: 100; height: 30; color: "yellow"
Text { id: textItem }
}
以下代碼將為Button
子Text對象創(chuàng)建一個(gè)具有定義的文本字符串的:
Button { buttonText: "Click Me" }
在這里登澜,修改buttonText
直接修改了textItem.text值;它不會更改其他值飘庄,然后更新textItem.text脑蠕。如果buttonText
不是別名,則更改其值實(shí)際上根本不會更改顯示的文本,因?yàn)閷傩越壎ú皇请p向的:buttonText
如果更改了textItem.text谴仙,則值將已更改迂求,但反之則沒有。
屬性別名的注意事項(xiàng)
僅在組件完全初始化后才能激活別名晃跺。當(dāng)引用未初始化的別名時(shí)揩局,將生成錯(cuò)誤。同樣掀虎,對別名屬性進(jìn)行別名也將導(dǎo)致錯(cuò)誤凌盯。
property alias widgetLabel: label
//will generate an error
//widgetLabel.text: "Initial text"
//will generate an error
//property alias widgetLabelText: widgetLabel.text
Component.onCompleted: widgetLabel.text = "Alias completed Initialization"
但是,當(dāng)在根對象中導(dǎo)入帶有屬性別名的QML對象類型時(shí)烹玉,該屬性顯示為常規(guī)Qt屬性十气,因此可以在別名引用中使用。
別名屬性可能與現(xiàn)有屬性具有相同的名稱春霍,從而有效覆蓋現(xiàn)有屬性砸西。例如,以下QML類型具有color
別名屬性址儒,其名稱與內(nèi)置的Rectangle :: color屬性相同:
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"
}
}
使用此類型并引用其color
屬性的任何對象都將引用別名芹枷,而不是普通的Rectangle :: color屬性。但是莲趣,在內(nèi)部鸳慈,矩形可以正確設(shè)置其color
屬性并引用實(shí)際定義的屬性,而不是別名喧伞。
屬性別名和類型
屬性別名不能具有明確的類型規(guī)范走芋。屬性別名的類型是其引用的屬性或?qū)ο蟮?em>聲明類型。因此潘鲫,如果您為通過id引用的對象創(chuàng)建別名翁逞,并使用內(nèi)聯(lián)聲明的其他屬性,則無法通過別名訪問這些額外的屬性:
// MyItem.qml
Item {
property alias inner: innerItem
Item {
id: innerItem
property int extraProperty
}
}
您不能從此組件外部初始化inner.extraProperty溉仑,因?yàn)閕nner只是一個(gè)Item:
// main.qml
MyItem {
inner.extraProperty: 5 // fails
}
但是挖函,如果您使用專用的.qml文件將內(nèi)部對象提取到單獨(dú)的組件中,則可以實(shí)例化該組件浊竟,并通過別名使用其所有屬性:
// 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
}
默認(rèn)屬性
對象定義可以具有一個(gè)默認(rèn)屬性怨喘。默認(rèn)屬性是如果在另一個(gè)對象的定義中聲明一個(gè)對象但未將其聲明為特定屬性的值的情況下,為其分配值的屬性振定。
使用optional default
關(guān)鍵字聲明屬性會將其標(biāo)記為默認(rèn)屬性必怜。例如,假設(shè)有一個(gè)具有默認(rèn)屬性的文件MyLabel.qml someText
:
// MyLabel.qml
import QtQuick 2.0
Text {
default property var someText
text: "Hello, " + someText.text
}
該someText
值可以在MyLabel
對象定義中分配給它后频,如下所示:
MyLabel {
Text { text: "world!" }
}
與以下內(nèi)容完全相同:
MyLabel {
Text { text: "world!" }
}
但是梳庆,由于該someText
屬性已被標(biāo)記為默認(rèn)屬性,因此無需將Text對象顯式分配給該屬性。
您會注意到靠益,可以將子對象添加到任何基于Item的類型,而無需將其顯式添加到children屬性残揉。這是因?yàn)槟J(rèn)的屬性項(xiàng)目是其data
財(cái)產(chǎn)胧后,并添加到此列表中的任何項(xiàng)目項(xiàng)目會自動添加到其列表中的孩子。
默認(rèn)屬性對于重新分配項(xiàng)目的子項(xiàng)很有用抱环。請參見TabWidget示例壳快,該示例使用默認(rèn)屬性自動將TabWidget的子級重新分配為內(nèi)部ListView的子級。另請參見擴(kuò)展QML镇草。
只讀屬性
對象聲明可以使用readonly
關(guān)鍵字通過以下語法定義只讀屬性:
readonly property <propertyType> <propertyName> : <initialValue>
初始化時(shí)必須為只讀屬性分配一個(gè)值眶痰。初始化只讀屬性后,無論是從命令式代碼還是其他方式梯啤,都不再可以為其賦予值竖伯。
例如,Component.onCompleted
以下塊中的代碼無效:
Item {
readonly property int someNumber: 10
Component.onCompleted: someNumber = 20
// doesn't work, causes an error
}
注意:只讀屬性也不能是默認(rèn)屬性因宇。
屬性修改器對象
屬性可以具有與其關(guān)聯(lián)的屬性值修改器對象七婴。聲明與特定屬性關(guān)聯(lián)的屬性修飾符類型的實(shí)例的語法如下:
<PropertyModifierTypeName> on <propertyName> {
// attributes of the object instance
}
重要的是要注意,以上語法實(shí)際上是一個(gè)對象聲明察滑,它將實(shí)例化作用于預(yù)先存在的屬性的對象打厘。
某些屬性修飾符類型可能僅適用于特定的屬性類型,但這不是語言所強(qiáng)制執(zhí)行的贺辰。例如户盯,所NumberAnimation
提供的類型QtQuick
將僅對數(shù)字類型的屬性(例如int
或real
)進(jìn)行動畫處理。嘗試使用NumberAnimation
具有非數(shù)字屬性的不會導(dǎo)致錯(cuò)誤饲化,但是不會為非數(shù)字屬性設(shè)置動畫莽鸭。屬性修改器類型與特定屬性類型相關(guān)聯(lián)時(shí)的行為由其實(shí)現(xiàn)方式定義。
信號屬性
信號是來自某個(gè)對象的通知吃靠,表明發(fā)生了某些事件:例如蒋川,屬性已更改,動畫已開始或停止或下載圖像時(shí)撩笆。在鼠標(biāo)區(qū)域類型捺球,例如,有一個(gè)被點(diǎn)擊時(shí)發(fā)射當(dāng)鼠標(biāo)區(qū)域內(nèi)的用戶點(diǎn)擊信號夕冲。
每當(dāng)發(fā)出特定信號時(shí)氮兵,可以通過信號處理程序通知對象。使用on <Signal>語法聲明信號處理程序歹鱼,其中<Signal>是信號名稱泣栈,首字母大寫。必須在發(fā)出信號的對象的定義內(nèi)聲明信號處理程序,并且該處理程序應(yīng)包含在調(diào)用信號處理程序時(shí)要執(zhí)行的JavaScript代碼塊南片。
例如掺涛,下面的onClicked信號處理程序在MouseArea對象定義中聲明,并在單擊MouseArea時(shí)被調(diào)用疼进,從而導(dǎo)致控制臺消息被打有嚼隆:
import QtQuick 2.0
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Click!")
}
}
}
定義信號屬性
通過注冊一個(gè)類的Q_SIGNAL,然后在QML類型系統(tǒng)中注冊伞广,可以為C ++中的類型定義一個(gè)信號拣帽。或者嚼锄,可以使用以下語法在QML文檔的對象聲明中定義對象類型的自定義信號:
signal <signalName>[([<type> <parameter name>[, ...]])]
試圖在同一類型塊中聲明兩個(gè)具有相同名稱的信號或方法是錯(cuò)誤的减拭。但是,新信號可能會在類型上重復(fù)使用現(xiàn)有信號的名稱区丑。(這應(yīng)該謹(jǐn)慎行事拧粪,因?yàn)楝F(xiàn)有信號可能會被隱藏并變得難以訪問。)
這是信號聲明的三個(gè)示例:
import QtQuick 2.0
Item {
signal clicked
signal hovered()
signal actionPerformed(string action, var actionResult)
}
如果信號沒有參數(shù)沧侥,則“()”括號是可選的既们。如果使用了參數(shù),則必須聲明參數(shù)類型正什,如上述信號的string
和var
參數(shù)一樣actionPerformed
啥纸。允許的參數(shù)類型與此頁面上的“ 定義屬性屬性”下列出的參數(shù)類型相同。
要發(fā)出信號婴氮,請將其作為方法調(diào)用斯棒。發(fā)出信號時(shí),將調(diào)用任何相關(guān)的信號處理程序主经,并且處理程序可以使用定義的信號參數(shù)名稱來訪問相應(yīng)的參數(shù)荣暮。
屬性更改信號
QML類型還提供了內(nèi)置的屬性更改信號,每當(dāng)屬性值更改時(shí)都會發(fā)出該信號罩驻,如先前在屬性屬性部分中所述穗酥。有關(guān)這些信號為何有用以及如何使用它們的更多信息,請參見即將到來的關(guān)于屬性更改信號處理程序的部分惠遏。
信號處理程序?qū)傩?a target="_blank">
信號處理程序是一種特殊的方法屬性砾跃,只要發(fā)出關(guān)聯(lián)的信號,QML引擎就會調(diào)用該方法的實(shí)現(xiàn)节吮。在QML中向?qū)ο蠖x添加信號將自動向該對象定義添加關(guān)聯(lián)的信號處理程序抽高,該信號處理程序默認(rèn)情況下為空實(shí)現(xiàn)⊥讣ǎ客戶可以提供一種實(shí)現(xiàn)翘骂,以實(shí)現(xiàn)程序邏輯壁熄。
考慮以下SquareButton
類型,其定義在SquareButton.qml
文件中提供碳竟,如下所示草丧,并帶有信號activated
和deactivated
:
// 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()
}
}
這些信號可由SquareButton
同一目錄中另一個(gè)QML文件中的任何對象接收,其中信號處理程序的實(shí)現(xiàn)由客戶端提供:
// myapplication.qml
SquareButton {
onActivated: console.log("Activated at " + xPosition + "," + yPosition)
onDeactivated: console.log("Deactivated!")
}
有關(guān)信號使用的更多詳細(xì)信息莹桅,請參見信號和處理程序事件系統(tǒng)昌执。
屬性更改信號處理程序
屬性更改信號的信號處理程序采用on <Property> Changed的語法形式,其中<Property>是屬性的名稱统翩,首字母大寫。例如此洲,盡管TextInput類型文檔沒有記錄textChanged
信號厂汗,但由于TextInput具有text屬性,因此該信號是隱式可用的呜师,因此onTextChanged
只要此屬性發(fā)生更改娶桦,就可以編寫要調(diào)用的信號處理程序:
import QtQuick 2.0
TextInput {
text: "Change this!"
onTextChanged: console.log("Text has changed to:", text)
}
方法屬性
對象類型的方法是可以調(diào)用以執(zhí)行某些處理或觸發(fā)其他事件的功能≈梗可以將一種方法連接到信號衷畦,以便在發(fā)出信號時(shí)自動調(diào)用該方法。有關(guān)更多詳細(xì)信息知牌,請參見信號和處理程序事件系統(tǒng)祈争。
定義方法屬性
可以通過在C ++中為類型定義一種方法,方法是:標(biāo)記一個(gè)類的函數(shù)角寸,然后使用Q_INVOKABLE在QML類型系統(tǒng)中注冊該類菩混,或者將其注冊為該類的Q_SLOT”馀海或者沮峡,可以使用以下語法將自定義方法添加到QML文檔中的對象聲明中:
function <functionName>([<parameterName>[, ...]]) { <body> }
可以將方法添加到QML類型,以定義獨(dú)立的可重用的JavaScript代碼塊亿柑。這些方法可以在內(nèi)部或外部對象中調(diào)用邢疙。
與信號不同,方法參數(shù)類型不必聲明望薄,因?yàn)樗鼈兡J(rèn)為var
類型疟游。
試圖在同一類型塊中聲明兩個(gè)具有相同名稱的方法或信號是錯(cuò)誤的。但是痕支,新方法可以在類型上重用現(xiàn)有方法的名稱乡摹。(這應(yīng)該謹(jǐn)慎行事,因?yàn)楝F(xiàn)有方法可能會被隱藏并且變得無法訪問采转。)
下面是一個(gè)帶有分配值時(shí)調(diào)用的方法的Rectangle:calculateHeight()``height
import QtQuick 2.0
Rectangle {
id: rect function calculateHeight() {
return rect.width / 2;
}
width: 100
height: calculateHeight()
}
如果該方法具有參數(shù)聪廉,則可以在方法內(nèi)按名稱訪問它們瞬痘。在下面,當(dāng)單擊MouseArea時(shí)板熊,它會調(diào)用該moveTo()
方法框全,然后該方法可以引用接收newX
到的newY
參數(shù)和參數(shù)來重新放置文本:
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!"
}
}
附加屬性和附加信號處理程序
附加屬性和附加信號處理程序是使對象能夠使用其他屬性或信號處理程序進(jìn)行注釋的機(jī)制,而附加屬性或信號處理程序?qū)τ谠搶ο笫遣豢捎玫母汕L貏e是津辩,它們允許對象訪問與單個(gè)對象特別相關(guān)的屬性或信號。
QML類型實(shí)現(xiàn)可以選擇在C ++中創(chuàng)建具有特定屬性和信號的附加類型容劳。然后可以創(chuàng)建這種類型的實(shí)例喘沿,并在運(yùn)行時(shí)將其附加到特定對象,從而允許那些對象訪問附加類型的屬性和信號竭贩。通過為屬性和相應(yīng)的信號處理程序添加前綴附加類型的名稱來訪問它們蚜印。
對附加屬性和處理程序的引用采用以下語法形式:
<AttachingType>.<propertyName>
<AttachingType>.on<SignalName>
例如,ListView的類型有一個(gè)附加屬性ListView.isCurrentItem留量,可用于在每個(gè)委托對象的ListView窄赋。每個(gè)單獨(dú)的委托對象都可以使用它來確定它是否是視圖中當(dāng)前選中的項(xiàng)目:
import QtQuick 2.0
ListView {
width: 240; height: 320
model: 3 delegate: Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow"
}
}
在這種情況下,附加類型的名稱為ListView
楼熄,相關(guān)屬性為isCurrentItem
忆绰,因此附加屬性稱為ListView.isCurrentItem
。
附加的信號處理程序以相同的方式引用可岂。例如错敢,組件的創(chuàng)建過程完成后,通常使用Component.onCompleted附加信號處理程序來執(zhí)行一些JavaScript代碼缕粹。在下面的示例中伐债,一旦完全創(chuàng)建ListModel,Component.onCompleted
將自動調(diào)用其信號處理程序以填充模型:
import QtQuick 2.0
ListView {
width: 240; height: 320
model: ListModel {
id: listModel
Component.onCompleted: {
for (var i = 0; i < 10; i++)
listModel.append({"Name": "Item " + i})
}
}
delegate: Text { text: index }
}
由于附加類型的名稱為Component
并且該類型具有完整的信號致开,因此附加信號處理程序稱為Component.onCompleted
峰锁。
有關(guān)訪問附加屬性和信號處理程序的注釋
一個(gè)常見的錯(cuò)誤是假定附加屬性和信號處理程序可從已附加這些屬性的對象的子級直接訪問。不是這種情況双戳。附加類型的實(shí)例僅附加到特定對象虹蒋,而不附加到對象及其所有子對象。
例如飒货,下面是包含附件屬性的先前示例的修改版本魄衅。這次,委托是項(xiàng)目塘辅,而彩色矩形是該項(xiàng)目的子項(xiàng):
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.
}
}
}
這不能按預(yù)期方式工作晃虫,因?yàn)?code>ListView.isCurrentItem它僅附加在根委托對象上,而不附加在其子對象上扣墩。由于Rectangle是委托的子代哲银,而不是委托本身扛吞,因此它不能以形式訪問isCurrentItem
附加屬性ListView.isCurrentItem
。因此荆责,矩形應(yīng)isCurrentItem
通過根委托進(jìn)行訪問:
ListView {
//....
delegate: Item {
id: delegateItem
width: 100; height: 30
Rectangle {
width: 100; height: 30
color: delegateItem.ListView.isCurrentItem ? "red" : "yellow" // correct
}
}
}
現(xiàn)在滥比,delegateItem.ListView.isCurrentItem
正確引用isCurrentItem
委托的附加屬性。
枚舉屬性(Enumeration Attributes)
枚舉提供了一組固定的命名選項(xiàng)做院∶し海可以使用enum
關(guān)鍵字在QML中聲明它們:
// MyText.qml
Text {
enum TextType {
Normal, Heading
}
}
如上所示,枚舉類型(例如TextType
)和值(例如Normal
)必須以大寫字母開頭键耕。
通過<Type>.<EnumerationType>.<Value>
或引用值<Type>.<Value>
寺滚。
// 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
}
有關(guān)QML中枚舉用法的更多信息,請參見QML基本類型 枚舉文檔屈雄。
Qt 5.10中引入了在QML中聲明枚舉的功能村视。