QT - QML對(duì)象屬性

QML對(duì)象屬性

每個(gè)QML對(duì)象類型都有一組定義的屬性。使用為該對(duì)象類型定義的屬性集創(chuàng)建對(duì)象類型的每個(gè)實(shí)例??梢灾付◣追N不同的屬性,如下所述。

對(duì)象聲明中的屬性

QML文檔中的對(duì)象聲明(object declaration)定義了一種新類型。它還聲明了一個(gè)對(duì)象層次結(jié)構(gòu),如果創(chuàng)建該新定義類型的實(shí)例,則將實(shí)例化該對(duì)象層次結(jié)構(gòu)。

QML對(duì)象類型屬性類型的集合如下:

  • ID屬性
  • 屬性屬性
  • 信號(hào)屬性
  • 信號(hào)處理程序?qū)傩?/li>
  • 方法屬性
  • 附加屬性和附加信號(hào)處理程序?qū)傩?/li>
  • 枚舉屬性

這些屬性將在下面詳細(xì)討論。

ID屬性

每個(gè)QML對(duì)象類型都有一個(gè)唯一的id屬性。此屬性由語言本身提供,并且不能由任何QML對(duì)象類型重新定義或覆蓋。

可以將值分配給對(duì)象實(shí)例的id屬性,以允許該對(duì)象被其他對(duì)象標(biāo)識(shí)和引用。它id必須以小寫字母或下劃線開頭,并且不能包含字母,數(shù)字和下劃線以外的字符。

import  QtQuick  2.0  
Column  {
  width:  200;  height:  200
  TextInput  {  id:  myTextInput;  text:  "Hello World"  }
  Text  {  text:  myTextInput.text  }
}

可以在聲明對(duì)象id組件范圍內(nèi)的任何位置引用該對(duì)象。因此,id值在其組成范圍內(nèi)必須始終是唯一的。有關(guān)更多信息,請(qǐng)參見作用域和命名分辨率。

創(chuàng)建對(duì)象實(shí)例后,無法更改其id屬性的值。盡管它看起來像是普通屬性,但該id屬性不是普通property屬性,并且特殊語義適用于此屬性;例如,myTextInput.id在上面的示例中無法訪問。

屬性Property

屬性是可以分配靜態(tài)值或綁定到動(dòng)態(tài)表達(dá)式的對(duì)象的屬性。一個(gè)屬性的值可以被其他對(duì)象讀取。通常,它也可以由另一個(gè)對(duì)象修改,除非特定的QML類型明確禁止特定屬性使用。

定義Property屬性

通過注冊(cè)類的Q_PROPERTY,然后再向QML類型系統(tǒng)注冊(cè),可以在C ++中為類型定義屬性?;蛘?,可以使用以下語法在QML文檔的對(duì)象聲明中定義對(duì)象類型的自定義屬性:

[default] property <propertyType> <propertyName>

這樣,對(duì)象聲明可以將特定的值暴露給外部對(duì)象,或者更容易維護(hù)一些內(nèi)部狀態(tài)。

屬性名稱必須以小寫字母開頭,并且只能包含字母,數(shù)字和下劃線。JavaScript保留字不是有效的屬性名稱。該default關(guān)鍵字是可選的,并修改所聲明的屬性的語義。有關(guān)屬性修飾符的更多信息,請(qǐng)參見后面的默認(rèn)屬性部分default。

聲明自定義屬性會(huì)隱式創(chuàng)建該屬性的值更改信號(hào),以及一個(gè)名為on <PropertyName> Changed的關(guān)聯(lián)信號(hào)處理程序,其中<PropertyName>屬性的名稱,首字母大寫。

例如,以下對(duì)象聲明定義了一個(gè)從Rectangle基本類型派生的新類型。它具有兩個(gè)新屬性,并為這些新屬性之一實(shí)現(xiàn)了信號(hào)處理程序

  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ì)信息,請(qǐng)參見QML基本類型文檔。

請(qǐng)注意,var基本類型是通用占位符類型,可以保存任何類型的值,包括列表和對(duì)象:

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對(duì)象類型都可以用作屬性類型。例如:

property Item someItem
property Rectangle someRectangle

這也適用于自定義QML類型。如果在名為ColorfulButton.qml(在隨后由客戶端導(dǎo)入的目錄中)文件中定義了QML類型,則type屬性ColorfulButton也將有效。

將值分配給屬性

可以通過兩種不同的方式指定對(duì)象實(shí)例的屬性的值:

  • 初始化時(shí)的值分配
  • 必要的價(jià)值分配

無論哪種情況,該值都可以是靜態(tài)值或綁定表達(dá)式值。

初始化時(shí)的值分配

在初始化時(shí)為屬性分配值的語法是:

<propertyName> : <value>

如果需要,可以將初始化值分配與對(duì)象聲明中的屬性定義組合。在這種情況下,屬性定義的語法變?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引擎都會(huì)自動(dòng)重新計(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)更多信息,請(qǐng)參見屬性綁定。

類型安全

屬性是類型安全的。只能為屬性分配與屬性類型匹配的值。

例如,如果一個(gè)屬性是一個(gè)實(shí)數(shù),并且如果您嘗試為其分配一個(gè)字符串,則會(huì)出現(xiàn)錯(cuò)誤:

property int volume: "four"  // generates an error; the property's object will not be loaded

同樣,如果在運(yùn)行時(shí)為屬性分配了錯(cuò)誤類型的值,則不會(huì)分配新值,并且會(huì)生成錯(cuò)誤。

某些屬性類型沒有自然值表示形式,對(duì)于這些屬性類型,QML引擎自動(dòng)執(zhí)行字符串到類型值的轉(zhuǎn)換。因此,例如,即使color類型的屬性存儲(chǔ)顏色而不是字符串,您也可以將字符串分配給"red"color屬性,而不會(huì)報(bào)告錯(cuò)誤。

有關(guān)默認(rèn)支持的屬性類型的列表,請(qǐng)參見QML基本類型。另外,任何可用的QML對(duì)象類型也可以用作屬性類型。

特殊財(cái)產(chǎn)類型

對(duì)象列表屬性屬性

列表類型屬性可被分配QML對(duì)象類型值的列表。定義對(duì)象列表值的語法是用方括號(hào)括起來的逗號(hào)分隔列表:

[ <item 1>, <item 2>, ... ]

例如,Item類型具有一個(gè)states屬性,該屬性用于保存State類型對(duì)象的列表。下面的代碼將該屬性的值初始化為三個(gè)State對(duì)象的列表:

  import  QtQuick  2.0
  Item  {
      states:  [
          State  {  name:  "loading"  },
          State  {  name:  "running"  },
          State  {  name:  "stopped"  }
      ]
  }

如果列表包含單個(gè)項(xiàng)目,則可以省略方括號(hào):

  import  QtQuick  2.0
  Item  {
      states:  State  {  name:  "running"  }
  }

列表類型屬性可以與下面的語法的對(duì)象聲明中指定:

[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è)屬性來存儲(chǔ)值列表,這些列表不一定是QML對(duì)象類型的值,則應(yīng)該聲明一個(gè)var屬性。

分組屬性

在某些情況下,屬性包含一組邏輯的子屬性屬性??梢允褂命c(diǎn)符號(hào)或組符號(hào)將這些子屬性屬性分配給它們。

例如,“ 文本”類型具有字體組屬性。下面,第一個(gè)Text對(duì)象font使用點(diǎn)表示法初始化其值,而第二個(gè)對(duì)象使用組表示法:

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)更多信息,請(qǐng)參見有關(guān)QML基本類型的文檔。

屬性別名(Property Aliases)

屬性別名是保存對(duì)另一個(gè)屬性的引用的屬性。與為屬性分配新的唯一存儲(chǔ)空間的普通屬性定義不同,屬性別名將新聲明的屬性(稱為別名屬性)連接為對(duì)現(xiàn)有屬性(別名屬性)的直接引用。

屬性別名聲明看起來像普通的屬性定義,只是它需要alias關(guān)鍵字而不是屬性類型,并且屬性聲明的右側(cè)必須是有效的別名引用:

[default] property alias <name>: <alias reference>

與普通屬性不同,別名具有以下限制:

  • 它只能引用在聲明別名的類型范圍內(nèi)的對(duì)象或?qū)ο蟮膶傩浴?/li>
  • 它不能包含任意JavaScript表達(dá)式
  • 它不能引用在其類型范圍之外聲明的對(duì)象。
  • 別名引用是不可選的,不像普通的財(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別名屬性的類型,該類型連接到Texttext對(duì)象的對(duì)象:

  // Button.qml
  import  QtQuick  2.0
  Rectangle  {
      property  alias  buttonText:  textItem.text
      width:  100;  height:  30;  color:  "yellow"
      Text  {  id:  textItem  }
  }

以下代碼將為ButtonText對(duì)象創(chuàng)建一個(gè)具有定義的文本字符串的:

  Button {  buttonText:  "Click Me"  }

在這里,修改buttonText直接修改了textItem.text值;它不會(huì)更改其他值,然后更新textItem.text。如果buttonText不是別名,則更改其值實(shí)際上根本不會(huì)更改顯示的文本,因?yàn)閷傩越壎ú皇请p向的:buttonText如果更改了textItem.text,則值將已更改,但反之則沒有。

屬性別名的注意事項(xiàng)

僅在組件完全初始化后才能激活別名。當(dāng)引用未初始化的別名時(shí),將生成錯(cuò)誤。同樣,對(duì)別名屬性進(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)在根對(duì)象中導(dǎo)入帶有屬性別名的QML對(duì)象類型時(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屬性的任何對(duì)象都將引用別名,而不是普通的Rectangle :: color屬性。但是,在內(nèi)部,矩形可以正確設(shè)置其color屬性并引用實(shí)際定義的屬性,而不是別名。

屬性別名和類型

屬性別名不能具有明確的類型規(guī)范。屬性別名的類型是其引用的屬性或?qū)ο蟮?em>聲明類型。因此,如果您為通過id引用的對(duì)象創(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)部對(duì)象提取到單獨(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)屬性

對(duì)象定義可以具有一個(gè)默認(rèn)屬性。默認(rèn)屬性是如果在另一個(gè)對(duì)象的定義中聲明一個(gè)對(duì)象但未將其聲明為特定屬性的值的情況下,為其分配值的屬性。

使用optional default關(guān)鍵字聲明屬性會(huì)將其標(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對(duì)象定義中分配給它,如下所示:

  MyLabel  {
      Text  {  text:  "world!"  }
  }

與以下內(nèi)容完全相同:

  MyLabel  {
      Text  {  text:  "world!"  }
  }

但是,由于該someText屬性已被標(biāo)記為默認(rèn)屬性,因此無需將Text對(duì)象顯式分配給該屬性。

您會(huì)注意到,可以將子對(duì)象添加到任何基于Item的類型,而無需將其顯式添加到children屬性。這是因?yàn)槟J(rèn)的屬性項(xiàng)目是其data財(cái)產(chǎn),并添加到此列表中的任何項(xiàng)目項(xiàng)目會(huì)自動(dòng)添加到其列表中的孩子

默認(rèn)屬性對(duì)于重新分配項(xiàng)目的子項(xiàng)很有用。請(qǐng)參見TabWidget示例,該示例使用默認(rèn)屬性自動(dòng)將TabWidget的子級(jí)重新分配為內(nèi)部ListView的子級(jí)。另請(qǐng)參見擴(kuò)展QML

只讀屬性

對(duì)象聲明可以使用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)屬性。

屬性修改器對(duì)象

屬性可以具有與其關(guān)聯(lián)的屬性值修改器對(duì)象。聲明與特定屬性關(guān)聯(lián)的屬性修飾符類型的實(shí)例的語法如下:

<PropertyModifierTypeName> on <propertyName> {
    // attributes of the object instance
}

重要的是要注意,以上語法實(shí)際上是一個(gè)對(duì)象聲明,它將實(shí)例化作用于預(yù)先存在的屬性的對(duì)象。

某些屬性修飾符類型可能僅適用于特定的屬性類型,但這不是語言所強(qiáng)制執(zhí)行的。例如,所NumberAnimation提供的類型QtQuick將僅對(duì)數(shù)字類型的屬性(例如intreal)進(jìn)行動(dòng)畫處理。嘗試使用NumberAnimation具有非數(shù)字屬性的不會(huì)導(dǎo)致錯(cuò)誤,但是不會(huì)為非數(shù)字屬性設(shè)置動(dòng)畫。屬性修改器類型與特定屬性類型相關(guān)聯(lián)時(shí)的行為由其實(shí)現(xiàn)方式定義。

信號(hào)屬性

信號(hào)是來自某個(gè)對(duì)象的通知,表明發(fā)生了某些事件:例如,屬性已更改,動(dòng)畫已開始或停止或下載圖像時(shí)。在鼠標(biāo)區(qū)域類型,例如,有一個(gè)被點(diǎn)擊時(shí)發(fā)射當(dāng)鼠標(biāo)區(qū)域內(nèi)的用戶點(diǎn)擊信號(hào)。

每當(dāng)發(fā)出特定信號(hào)時(shí),可以通過信號(hào)處理程序通知對(duì)象。使用on <Signal>語法聲明信號(hào)處理程序,其中<Signal>信號(hào)名稱,首字母大寫。必須在發(fā)出信號(hào)的對(duì)象的定義內(nèi)聲明信號(hào)處理程序,并且該處理程序應(yīng)包含在調(diào)用信號(hào)處理程序時(shí)要執(zhí)行的JavaScript代碼塊。

例如,下面的onClicked信號(hào)處理程序在MouseArea對(duì)象定義中聲明,并在單擊MouseArea時(shí)被調(diào)用,從而導(dǎo)致控制臺(tái)消息被打?。?/p>

    import  QtQuick  2.0
    Item  {
          width:  100;  height:  100
          MouseArea  {
              anchors.fill:  parent
              onClicked:  {
                  console.log("Click!")
              }
          }
    }

定義信號(hào)屬性

通過注冊(cè)一個(gè)類的Q_SIGNAL,然后在QML類型系統(tǒng)中注冊(cè),可以為C ++中的類型定義一個(gè)信號(hào)。或者,可以使用以下語法在QML文檔的對(duì)象聲明中定義對(duì)象類型的自定義信號(hào):

signal <signalName>[([<type> <parameter name>[, ...]])]

試圖在同一類型塊中聲明兩個(gè)具有相同名稱的信號(hào)或方法是錯(cuò)誤的。但是,新信號(hào)可能會(huì)在類型上重復(fù)使用現(xiàn)有信號(hào)的名稱。(這應(yīng)該謹(jǐn)慎行事,因?yàn)楝F(xiàn)有信號(hào)可能會(huì)被隱藏并變得難以訪問。)

這是信號(hào)聲明的三個(gè)示例:

import  QtQuick  2.0
  Item  {
        signal clicked
         signal hovered()
         signal actionPerformed(string action,  var actionResult)
  }

如果信號(hào)沒有參數(shù),則“()”括號(hào)是可選的。如果使用了參數(shù),則必須聲明參數(shù)類型,如上述信號(hào)的stringvar參數(shù)一樣actionPerformed。允許的參數(shù)類型與此頁面上的“ 定義屬性屬性”下列出的參數(shù)類型相同。

要發(fā)出信號(hào),請(qǐng)將其作為方法調(diào)用。發(fā)出信號(hào)時(shí),將調(diào)用任何相關(guān)的信號(hào)處理程序,并且處理程序可以使用定義的信號(hào)參數(shù)名稱來訪問相應(yīng)的參數(shù)。

屬性更改信號(hào)

QML類型還提供了內(nèi)置的屬性更改信號(hào),每當(dāng)屬性值更改時(shí)都會(huì)發(fā)出該信號(hào),如先前在屬性屬性部分中所述。有關(guān)這些信號(hào)為何有用以及如何使用它們的更多信息,請(qǐng)參見即將到來的關(guān)于屬性更改信號(hào)處理程序的部分。

信號(hào)處理程序?qū)傩?a target="_blank">

信號(hào)處理程序是一種特殊的方法屬性,只要發(fā)出關(guān)聯(lián)的信號(hào),QML引擎就會(huì)調(diào)用該方法的實(shí)現(xiàn)。在QML中向?qū)ο蠖x添加信號(hào)將自動(dòng)向該對(duì)象定義添加關(guān)聯(lián)的信號(hào)處理程序,該信號(hào)處理程序默認(rèn)情況下為空實(shí)現(xiàn)??蛻艨梢蕴峁┮环N實(shí)現(xiàn),以實(shí)現(xiàn)程序邏輯。

考慮以下SquareButton類型,其定義在SquareButton.qml文件中提供,如下所示,并帶有信號(hào)activateddeactivated

  // 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()
        }
  }

這些信號(hào)可由SquareButton同一目錄中另一個(gè)QML文件中的任何對(duì)象接收,其中信號(hào)處理程序的實(shí)現(xiàn)由客戶端提供:

// myapplication.qml
SquareButton {
    onActivated: console.log("Activated at " + xPosition + "," + yPosition)
    onDeactivated: console.log("Deactivated!")
}

有關(guān)信號(hào)使用的更多詳細(xì)信息,請(qǐng)參見信號(hào)和處理程序事件系統(tǒng)。

屬性更改信號(hào)處理程序

屬性更改信號(hào)的信號(hào)處理程序采用on <Property> Changed的語法形式,其中<Property>屬性的名稱,首字母大寫。例如,盡管TextInput類型文檔沒有記錄textChanged信號(hào),但由于TextInput具有text屬性,因此該信號(hào)是隱式可用的,因此onTextChanged只要此屬性發(fā)生更改,就可以編寫要調(diào)用的信號(hào)處理程序:

  import  QtQuick  2.0
  TextInput  {
      text:  "Change this!"
      onTextChanged:  console.log("Text has changed to:",  text)
  }

方法屬性

對(duì)象類型的方法是可以調(diào)用以執(zhí)行某些處理或觸發(fā)其他事件的功能??梢詫⒁环N方法連接到信號(hào),以便在發(fā)出信號(hào)時(shí)自動(dòng)調(diào)用該方法。有關(guān)更多詳細(xì)信息,請(qǐng)參見信號(hào)和處理程序事件系統(tǒng)。

定義方法屬性

可以通過在C ++中為類型定義一種方法,方法是:標(biāo)記一個(gè)類的函數(shù),然后使用Q_INVOKABLE在QML類型系統(tǒng)中注冊(cè)該類,或者將其注冊(cè)為該類的Q_SLOT?;蛘?,可以使用以下語法將自定義方法添加到QML文檔中的對(duì)象聲明中:

function <functionName>([<parameterName>[, ...]]) { <body> }

可以將方法添加到QML類型,以定義獨(dú)立的可重用的JavaScript代碼塊。這些方法可以在內(nèi)部或外部對(duì)象中調(diào)用。

與信號(hào)不同,方法參數(shù)類型不必聲明,因?yàn)樗鼈兡J(rèn)為var類型。

試圖在同一類型塊中聲明兩個(gè)具有相同名稱的方法或信號(hào)是錯(cuò)誤的。但是,新方法可以在類型上重用現(xiàn)有方法的名稱。(這應(yīng)該謹(jǐn)慎行事,因?yàn)楝F(xiàn)有方法可能會(huì)被隱藏并且變得無法訪問。)

下面是一個(gè)帶有分配值時(shí)調(diào)用的方法的RectanglecalculateHeight()``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í),它會(huì)調(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!"
      }
  }

附加屬性和附加信號(hào)處理程序

附加屬性附加信號(hào)處理程序是使對(duì)象能夠使用其他屬性或信號(hào)處理程序進(jìn)行注釋的機(jī)制,而附加屬性或信號(hào)處理程序?qū)τ谠搶?duì)象是不可用的。特別是,它們?cè)试S對(duì)象訪問與單個(gè)對(duì)象特別相關(guān)的屬性或信號(hào)。

QML類型實(shí)現(xiàn)可以選擇在C ++中創(chuàng)建具有特定屬性和信號(hào)附加類型。然后可以創(chuàng)建這種類型的實(shí)例,并在運(yùn)行時(shí)將其附加到特定對(duì)象,從而允許那些對(duì)象訪問附加類型的屬性和信號(hào)。通過為屬性和相應(yīng)的信號(hào)處理程序添加前綴附加類型的名稱來訪問它們。

對(duì)附加屬性和處理程序的引用采用以下語法形式:

<AttachingType>.<propertyName>
<AttachingType>.on<SignalName>

例如,ListView的類型有一個(gè)附加屬性ListView.isCurrentItem,可用于在每個(gè)委托對(duì)象的ListView。每個(gè)單獨(dú)的委托對(duì)象都可以使用它來確定它是否是視圖中當(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。

附加的信號(hào)處理程序以相同的方式引用。例如,組件的創(chuàng)建過程完成后,通常使用Component.onCompleted附加信號(hào)處理程序來執(zhí)行一些JavaScript代碼。在下面的示例中,一旦完全創(chuàng)建ListModel,Component.onCompleted將自動(dòng)調(diào)用其信號(hà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并且該類型具有完整的信號(hào),因此附加信號(hào)處理程序稱為Component.onCompleted。

有關(guān)訪問附加屬性和信號(hào)處理程序的注釋

一個(gè)常見的錯(cuò)誤是假定附加屬性和信號(hào)處理程序可從已附加這些屬性的對(duì)象的子級(jí)直接訪問。不是這種情況。附加類型的實(shí)例僅附加到特定對(duì)象,而不附加到對(duì)象及其所有子對(duì)象。

例如,下面是包含附件屬性的先前示例的修改版本。這次,委托是項(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它附加在根委托對(duì)象上,而不附加在其子對(duì)象上。由于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)??梢允褂?code>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中枚舉用法的更多信息,請(qǐng)參見QML基本類型 枚舉文檔。

Qt 5.10中引入了在QML中聲明枚舉的功能。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容