QML Object Attributes QML對象屬性

QML Object Attributesexpress

Every QML object type has a defined set of attributes. Each instance of an object type is created with the set of attributes that have been defined for that object type. There are several different kinds of attributes which can be specified, which are described below.api

每個QML對象類型都定義了一系列屬性。每建立一個對象類型的實例,對象內定義的一系列屬性就會被建立。接下來咱們討論有哪幾種不一樣種類的屬性可被指定。安全

Attributes in Object Declarationsapp

對象聲明內的屬性less

An object declaration in a QML document defines a new type. It also declares an object hierarchy that will be instantiated should an instance of that newly defined type be created.ide

QML文檔內的對象聲明定義一個新的類型。也聲明瞭以新定義的類型爲實例的將被實例化的對象層次結構的建立。函數

The set of QML object-type attribute types is as follows:動畫

這組QML對象系統的屬性類型以下:ui

the id attributethis

property attributes

signal attributes

signal handler attributes

method attributes

attached properties and attached signal handler attributes

id屬性

屬性特徵

信號屬性

信號處理屬性

方法屬性

附加屬性和附加信號處理屬性

These attributes are discussed in detail below.

下面詳細討論這些屬性:

The id Attribute

id 屬性

Every QML object type has exactly one id attribute. This attribute is provided by the language itself, and cannot be redefined or overridden by any QML object type.

每個QML對象類型都有一個惟一肯定的ID屬性。這個屬性是由語言自身提供的,而且不能被QML對象類型重定義或者重寫。

A value may be assigned to the id attribute of an object instance to allow that object to be identified and referred to by other objects. This id must begin with a lower-case letter or an underscore, and cannot contain characters other than letters, numbers and underscores.

能夠分配值給對象實例的id屬性讓對象被其它對象識別和引用。id必須以小寫字母或者下劃線開頭,而且不能包含除了字母數字和下劃線之外的字符。

Below is a TextInput object and a Text object. The TextInput object's id value is set to "myTextInput". The Text object sets its text property to have the same value as the text property of the TextInput, by referring to myTextInput.text. Now, both items will display the same text:

下面是一個 TextInput 對象和一個 Text 對象。 TextInput 對象的 id 值被設置爲 "myTextInput" 。 Text 對象設置本身的文本屬性和 TextInput 文本屬性有相同的值,經過引用 myTextInput.text 。如今,2個項將顯示相同的文本:

import QtQuick 2.0

Column {
    width: 200; height: 200

    TextInput { id: myTextInput; text: "Hello World" }

    Text { text: myTextInput.text }
}

An object can be referred to by its id from anywhere within the component scope in which it is declared. Therefore, an id value must always be unique within its component scope. See Scope and Naming Resolution for more information.

在對象被聲明的組件範圍內的任何地方,經過對象id引用對象。所以,id 值必須是組件範圍內惟一的。更多的細節請查看範圍<Scope>和命名方案<Naming Resolution>。

Once an object instance is created, the value of its id attribute cannot be changed. While it may look like an ordinary property, the id attribute is not an ordinary property attribute, and special semantics apply to it; for example, it is not possible to access myTextInput.id in the above example.

一旦對象實例被建立,它的id屬性值不能被改變。雖然它看起來像一個普通的屬性,可是其實它不是一個普通的屬性,而且特殊的語義應用與它;例如,在上面的例子中是不可能訪問 myTextInput.id 的。

Property Attributes

屬性特徵

A property is an attribute of an object that can be assigned a static value or bound to a dynamic expression. A property's value can be read by other objects. Generally it can also be modified by another object, unless a particular QML type has explicitly disallowed this for a specific property.

屬性是對象的特徵,能夠分配靜態值或綁定動態表達式到屬性。屬性的值能夠被其它對象讀取。

一般它也能被另外一個對象修改,除非某 QML 類型顯式的禁止修改某指定屬性。

Defining Property Attributes

定義屬性特徵

A property may be defined for a type in C++ by registering a Q_PROPERTY of a class which is then registered with the QML type system. Alternatively, a custom property of an object type may be defined in an object declaration in a QML document with the following syntax:

能夠經過在C++中註冊一個 Q_PROPERTY 到即將被註冊進QML類型系統的類來定義屬性。另外,一個對象類型的自定義屬性能夠在對象聲明時被定義,在QML文檔中使用以下的語法:

    [default] property <propertyType> <propertyName>

In this way an object declaration may expose a particular value to outside objects or maintain some internal state more easily.

經過這種方法一個對象聲明能夠暴露一個特殊的值到對象以外或者更容易保持一些內部狀態。

Property names must begin with a lower case letter and can only contain letters, numbers and underscores. JavaScript reserved words are not valid property names. The default keyword is optional, and modifies the semantics of the property being declared. See the upcoming section on default properties for more information about the default property modifier.

屬性名必須以小寫字母或者下劃線開頭,而且不能包含除了字母數字和下劃線之外的字符。JavaScript 保留字是無效的屬性名。默認關鍵字是可選的,將修改屬性聲明時的語義。查看下面的默認屬性的章節瞭解關於默認屬性修改的更多信息。

Declaring a custom property implicitly creates a value-change signal for that property, as well as an associated signal handler called on<PropertyName>Changed, where <PropertyName> is the name of the property, with the first letter capitalized.

聲明一個自定義屬性默認的爲此屬性建立了一個值改變信號,相關的信號是 on<PropertyName>Changed ,<PropertyName>是第一個字母大寫的屬性名。

For example, the following object declaration defines a new type which derives from the Rectangle base type. It has two new properties, with a signal handler implemented for one of those new properties:

例如,以下的對象聲明基於 Rectangle 定義了一個新類型,它有2個新屬性,對這兩個屬性中的一個實現了信號處理:

Rectangle {
    property color previousColor
    property color nextColor
    onNextColorChanged: console.log("The next color will be: " + nextColor.toString())
}

Valid Types in Custom Property Definitions

有效的自定義屬性類型

Any of the QML Basic Types aside from the enumeration type can be used as custom property types. For example, these are all valid property declarations:

除枚舉類型外,任何的QML基本類型能夠用來自定義屬性類型。例如,這些都是有效的屬性聲明:

Item {
    property int someNumber
    property string someString
    property url someUrl
}

(Enumeration values are simply whole number values and can be referred to with the int type instead.)

(枚舉值是整數值並能夠被相關的整型代替。)

Some basic types are provided by the QtQuick module and thus cannot be used as property types unless the module is imported. See the QML Basic Types documentation for more details.

QtQuick模塊提供的基本類型是不能做爲屬性類型使用的,除非導入模塊。更多的細節請查看QML基本類型<QML Basic Types>。

Note the var basic type is a generic placeholder type that can hold any type of value, including lists and objects:

注意基本類型 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" }

Additionally, any QML object type can be used as a property type. For example:

此外,任何 QML 對象類型能夠做爲屬性類型被使用。例如:

property Item someItem

property Rectangle someRectangle

This applies to custom QML types as well. If a QML type was defined in a file named ColorfulButton.qml (in a directory which was then imported by the client), then a property of type ColorfulButton would also be valid.

這也適用於自定義QML類型。若是在 ColorfulButton.qml 文件中定義了一個QML類型,那麼 ColorfulButton 類型的屬性也是有效的。

Assigning Values to Property Attributes

屬性特徵的值分配

The value of a property of an object instance may specified in two separate ways:

對象實例的屬性值能夠用2種獨立的方法指定:

a value assignment on initialization

an imperative value assignment

初始化賦值

命令式賦值

In either case, the value may be either a static value or a binding expression value.

任何狀況下,所賦的值或者是靜態值或者是綁定表達式值。

Value Assignment on Initialization

初始化賦值

The syntax for assigning a value to a property on initialization is:

屬性的初始化賦值的語法是:

    <propertyName> : <value>

An initialization value assignment may be combined with a property definition in an object declaration, if desired. In that case, the syntax of the property definition becomes:

初始化賦值能夠結合對象聲明時的屬性定義,若是須要。這種狀況下,屬性定義的的語法變爲:

    [default] property <propertyType> <propertyName> : <value>

An example of property value initialization follows:

一個屬性值初始化的例子以下:

import QtQuick 2.0

Rectangle {
    color: "red"
    property color nextColor: "blue" // combined property declaration and initialization
}

Imperative Value Assignment

命令賦值

An imperative value assignment is where a property value (either static value or binding expression) is assigned to a property from imperative JavaScript code. The syntax of an imperative value assignment is just the JavaScript assignment operator, as shown below:

命令賦值是從命令式的 JavaScript 代碼給一個屬性分配值。命令賦值的語法就是一個 JavaScript 賦值操做,以下:

    [<objectId>.]<propertyName> = value

An example of imperative value assignment follows:

以下是一個命令賦值的例子:

import QtQuick 2.0

Rectangle {
    id: rect
    Component.onCompleted: {
        rect.color = "red"
    }
}

Static Values and Binding Expression Values

靜態值和綁定表達式的值

As previously noted, there are two kinds of values which may be assigned to a property: static values, and binding expression values. The latter are also known as property bindings.

如前所述,有2種類型的值能夠分配給屬性:靜態值和綁定表達式的值。後者也被稱爲屬性綁定。

Kind Semantics

Static Value A constant value which does not depend on other properties.

Binding Expression A JavaScript expression which describes a property's relationship with other properties. The variables in this expression are called the property's dependencies.

The QML engine enforces the relationship between a property and its dependencies. When any of the dependencies change in value, the QML engine automatically re-evaluates the binding expression and assigns the new result to the property.

不依賴於其它屬性的常量值。

描述屬性與其它屬性關係的JavaScript表達式。表達式內的變量被稱爲屬性的依賴。QML引擎執行屬性和它的依賴之間的關係。當任何依賴的值改變,QML引擎自動對綁定的表達式從新求值並將新值賦值給屬性。

Here is an example that shows both kinds of values being assigned to properties:

這是一個顯示分配2種類型的值給屬性的例子:

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
    }
}

Note: To assign a binding expression imperatively, the binding expression must be contained in a function that is passed into Qt.binding(), and then the value returned by Qt.binding() must be assigned to the property. In contrast, Qt.binding() must not be used when assigning a binding expression upon initialization. See Property Binding for more information.

注意: 命令式地分配一個綁定表達式,此綁定表達式必須被包含在一個函數內,這個函數(做爲參數)被傳遞到 Qt.binding() ,Qt.binding() 返回的值必須被分配給屬性。相比之下,當分配一個綁定表達式在初始化上時,不須要使用 Qt.binding() 。更多的細節請查看屬性綁定<Property Binding>。

Type Safety

類型安全

Properties are type safe. A property can only be assigned a value that matches the property type.

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

For example, if a property is a real, and if you try to assign a string to it, you will get an error:

好比,若是屬性是實數,若是你嘗試分配字符串給它,你將獲得一個錯誤:

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

Likewise if a property is assigned a value of the wrong type during run time, the new value will not be assigned, and an error will be generated.

一樣,若是屬性在運行過程當中被分配錯誤的值,新值將不被分配,將產生一個錯誤。

Some property types do not have a natural value representation, and for those property types the QML engine automatically performs string-to-typed-value conversion. So, for example, even though properties of the color type store colors and not strings, you are able to assign the string "red" to a color property, without an error being reported.

有些屬性類型沒有天然值表現,對這些屬性類型QML引擎自動執行字符串到類型值的轉變。因此,例如,雖然顏色屬性儲存顏色而不是字符串,你也能夠分配"red"給一個顏色屬性,並不會報告錯誤。

See QML Basic Types for a list of the types of properties that are supported by default. Additionally, any available QML object type may also be used as a property type.

查看QML基本類型<QML Basic Types>列表,瞭解默認支持的屬性。另外,任何有效的QML基本類型也能夠被做爲屬性類型。

Special Property Types

特殊的屬性類型

Object List Property Attributes

對象列表屬性特徵

A list type property can be assigned a list of QML object-type values. The syntax for defining an object list value is a comma-separated list surrounded by square brackets:

列表類型的屬性能夠被分配一個(QML對象類型的)列表值。定義列表對象值的語法是被方括號包圍的逗號分割的列表。

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

For example, the Item type has a states property that is used to hold a list of State type objects. The code below initializes the value of this property to a list of three State objects:

好比,Item類型有一個用來控制State對象列表的states屬性。以下的代碼初始化一個屬性的值爲包含3個State對象(的列表):

import QtQuick 2.0

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

If the list contains a single item, the square brackets may be omitted:

若是列表只包含單獨項,能夠省略中括號:

import QtQuick 2.0

Item {
    states: State { name: "running" }
}

A list type property may be specified in an object declaration with the following syntax:

在對象聲明內可使用以下的語法指定列表類型的屬性:

[default] property list<<objectType>> propertyName

and, like other property declarations, a property initialization may be combined with the property declaration with the following syntax:

像其它的屬性聲明,屬性初始化能夠連同屬性聲明使用以下的語法:

[default] property list<<objectType>> propertyName: <value>

An example of list property declaration follows:

以下是一個列表屬性聲明的例子:

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"}
    ]
}

If you wish to declare a property to store a list of values which are not necessarily QML object-type values, you should declare a var property instead.

若是你想聲明一個屬性去儲存那些不須要 QML 對象類型的值的一個列表,你應該聲明一個 var 屬性代替。

Grouped Properties

屬性組

In some cases properties contain a logical group of sub-property attributes. These sub-property attributes can be assigned to using either the dot notation or group notation.

某些狀況下屬性包含子屬性特徵的邏輯組。這些子屬性特徵被分配到每個使用點(.)符號或組({})符號(的對象內)。

For example, the Text type has a font group property. Below, the first Text object initializes its font values using dot notation, while the second uses group notation:

例如, Text 類型有一個 font 組屬性。以下,第一個 Text 對象使用點符號初始化它的 font 值,而第二個(對象)使用組符號(初始化它的 font 值)。

Text {
    //dot notation
    font.pixelSize: 12
    font.b: true
}

Text {
    //group notation
    font { pixelSize: 12; b: true }
}

Grouped property types are basic types which have subproperties. Some of these basic types are provided by the QML language, while others may only be used if the Qt Quick module is imported. See the documentation about QML Basic Types for more information.

分組屬性類型是基本類型。一些基本類型是QML語言提供的,有一些在Qt Quick模塊被導入後才能使用。更多的細節請查看QML基本類型<QML Basic Types>。

Property Aliases

屬性別名

Property aliases are properties which hold a reference to another property. Unlike an ordinary property definition, which allocates a new, unique storage space for the property, a property alias connects the newly declared property (called the aliasing property) as a direct reference to an existing property (the aliased property).

屬性別名是另外一個屬性的引用。不一樣於通常的屬性定義(通常的屬性定義分配一個新的獨特的存儲空間),屬性別名鏈接新聲明的屬性做爲已存在屬性的直接引用。

A property alias declaration looks like an ordinary property definition, except that it requires the alias keyword instead of a property type, and the right-hand-side of the property declaration must be a valid alias reference:

屬性別名的聲明看起來像通常的屬性定義,除了它用 alias 關鍵字替代屬性類型,屬性聲明的右側必須是一個有效的別名引用:

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

Unlike an ordinary property, an alias can only refer to a object, or the property of a object, that is within the scope of the type within which the alias is declared. It cannot contain arbitrary JavaScript expressions and it cannot refer to objects declared outside of the scope of its type. Also note the alias reference is not optional, unlike the optional default value for an ordinary property; the alias reference must be provided when the alias is first declared.

不一樣於通常的屬性定義,別名只能指向別名被聲明的大括號內的對象或者對象的屬性。它不能包含任何的 JavaScript 表達式而且不能指向所在類型的大括號外聲明的對象。還要注意別名引用不是可選的,不像普通屬性的值有可選的默認值;別名引用(的對象)必須被提供當別名第一次聲明時。

For example, below is a Button type with a buttonText aliased property which is connected to the text object of the Text child:

例如,以下是一個帶 buttonText 別名的按鈕類型,別名鏈接到 Text 子對象的 text 對象:

// Button.qml
import QtQuick 2.0

Rectangle {
    property alias buttonText: textItem.text

    width: 100; height: 30; color: "yellow"

    Text { id: textItem }
}

The following code would create a Button with a defined text string for the child Text object:

下面的代碼會建立一個爲子 Text 對象定義了文本字符串的 Button:

Button { buttonText: "Click Me" }

Here, modifying buttonText directly modifies the textItem.text value; it does not change some other value that then updates textItem.text. If buttonText was not an alias, changing its value would not actually change the displayed text at all, as property bindings are not bi-directional: the buttonText value would have changed if textItem.text was changed, but not the other way around.

這裏,修改 buttonText 將直接修改 textItem.text 的值;不改變其它的值而後更新 textItem.text 。若是 buttonText 不是別名,改變他的值並不會改變顯示的文本,由於屬性綁定不是雙向的:若是 textItem.text 改變 buttonText 將會被改變,可是反過來就不行。

Considerations for Property Aliases

屬性別名的注意事項

Aliases are only activated once a component has been fully initialized. An error is generated when an uninitialized alias is referenced. Likewise, aliasing an aliasing property will also result in an error.

一旦組件被徹底初始化別名才被激活。未初始化的別名被引用將產生錯誤。一樣,別名到另外一個別名屬性也將產生錯誤。

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"

When importing a QML object type with a property alias in the root object, however, the property appear as a regular Qt property and consequently can be used in alias references.

當導入的的 QML 對象類型的根對象帶有屬性別名,不管如何,屬性呈現正常的的Qt屬性而且所以能被別名引用使用。

It is possible for an aliasing property to have the same name as an existing property, effectively overwriting the existing property. For example, the following QML type has a color alias property, named the same as the built-in Rectangle::color property:

別名屬性和已存在的屬性擁有相同的名字是可能的,事實上覆蓋了已存在屬性。例如,以下的 QML 類型有一個 color 屬性別名,和原有的 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"
    }
}

Any object that use this type and refer to its color property will be referring to the alias rather than the ordinary Rectangle::color property. Internally, however, the red can correctly set its color property and refer to the actual defined property rather than the alias.

任何對象使用這個類型而且指定它的 color 屬性將被引用到別名而不是原有的 Rectangle::color 屬性。可是,在內部紅色能夠正確設置它的顏色屬性而且指向實際定義的屬性,而不是別名。

Default Properties

默認屬性

An object definition can have a single default property. A default property is the property to which a value is assigned if an object is declared within another object's definition without declaring it as a value for a particular property.

對象定義能夠包含一個單獨的的默認屬性。若是一個對象(子)聲明在另外一個對象(父)的定義體內,默認屬性是(子對象內)一個被分配爲不須要聲明它做爲具體的屬性的值的屬性。

Declaring a property with the optional default keyword marks it as the default property. For example, say there is a file MyLabel.qml with a default property someText:

使用可選的 default 關鍵字聲明屬性爲默認屬性。例如,下面的 MyLabel.qml 文件內有一個默認屬性 someText:

// MyLabel.qml
import QtQuick 2.0

Text {
    default property var someText

    text: "Hello, " + someText.text
}

The someText value could be assigned to in a MyLabel object definition, like this:

someText 的值能夠被分配在 MyLabel 的對象定義內,以下:

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

This has exactly the same effect as the following:

以下有一樣的確切效果:

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

However, since the someText property has been marked as the default property, it is not necessary to explicitly assign the Text object to this property.

然而, someText 屬性被標記爲默認屬性,因此不須要顯式的分配 Text 對象的屬性名稱。

You will notice that child objects can be added to any Item-based type without explicitly adding them to the children property. This is because the default property of Item is its data property, and any items added to this list for an Item are automatically added to its list of children.

你也可能注意到了子對象能夠添加到任何基於Item的類型,而不須要顯式將它們添加到子屬性上。這是由於 Item 的默認屬性是 data 屬性,任何添加到 Item 中的對象都自動添加到它的子對象列表。

Default properties can be useful for reassigning the children of an item. See the TabWidget Example, which uses a default property to automatically reassign children of the TabWidget as children of an inner ListView.

默認屬性對於從新分配一個項的子項是有用的。查看 TabWidget 例子,使用默認屬性自動從新分配 TabWidget 的子對象做爲內部的 ListView 的子對象。

Read-Only Properties

只讀屬性

An object declaration may define a read-only property using the readonly keyword, with the following syntax:

對象聲明時使用readonly關鍵字能夠定義只讀屬性,語法以下:

    readonly property <propertyType> <propertyName> : <initialValue>

Read-only properties must be assigned a value on initialization. After a read-only property is initialized, it no longer possible to give it a value, whether from imperative code or otherwise.

只讀屬性必須在初始化時分配值。只讀屬性初始化後,不論是命令式代碼或者其它方式都不能夠再對它賦值。

For example, the code in the Component.onCompleted block below is invalid:

例如,Component.onCompleted 後的代碼快是無效的:

Item {
    readonly property int someNumber: 10

    Component.onCompleted: someNumber = 20  // doesn't work, causes an error
}

Note: A read-only property cannot also be a default property.

注意:只讀屬性不能是默認屬性。

Property Modifier Objects

屬性修改器對象

Properties can have property value modifier objects associated with them. The syntax for declaring an instance of a property modifier type associated with a particular property is as follows:

屬性能夠有屬性值修改器對象和他們關聯。聲明關聯到具體屬性的修改器類型實例的語法以下:

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

It is important to note that the above syntax is in fact an object declaration which will instantiate an object which acts on a pre-existing property.

一個很是重要的注意事項是以上的語法其實是一個對象的實例化的聲明,這個對象將做用在已存在的屬性。

Certain property modifier types may only be applicable to specific property types, however this is not enforced by the language. For example, the NumberAnimation type provided by QtQuick will only animate numeric-type (such as int or real) properties. Attempting to use a NumberAnimation with non-numeric property will not result in an error, however the non-numeric property will not be animated. The behavior of a property modifier type when associated with a particular property type is defined by its implementation.

某些屬性修改器類型可能只適用於特定的屬性類型,然而這不是被語言強制執行的。例如, QtQuick 提供的類型 NumberAnimation 類型僅動畫做用於數字類型的屬性。嘗試使用 NumberAnimation 到非數字類型屬性將不會獲得錯誤的結果,然而非數字類型的屬性將不會產生動畫。與特定屬性類型關聯的屬性修改器類型的行爲被它的實現定義。

Signal Attributes

信號屬性

A signal is a notification from an object that some event has occurred: for example, a property has changed, an animation has started or stopped, or when an image has been downloaded. The MouseArea type, for example, has a clicked signal that is emitted when the user clicks within the mouse area.

信號是當對象的一些事件發生時的消息:例如,屬性改變,動畫開始或結束,或者圖像被下載。拿 MouseArea 類型來講,當用戶點擊鼠標區域時會觸發一個 clicked 信號。

An object can be notified through a signal handler whenever it a particular signal is emitted. A signal handler is declared with the syntax on<Signal> where <Signal> is the name of the signal, with the first letter capitalized. The signal handler must be declared within the definition of the object that emits the signal, and the handler should contain the block of JavaScript code to be executed when the signal handler is invoked.

不管什麼時候特定的信號被觸發,能夠經過信號處理程序通知對象。信號處理程序使用 on<Signal> 語法聲明, <Signal> 是信號名,第一個字母大寫。信號處理程序必須聲明在觸發該信號的對象的定義內,而且處理程序應該包含 JavaScript 代碼塊當信號處理程序被調用時執行。

For example, the onClicked signal handler below is declared within the MouseArea object definition, and is invoked when the MouseArea is clicked, causing a console message to be printed:

好比,以下的 onClicked 信號處理程序被聲明在 MouseArea 對象定義內,而且當 MouseArea 被點擊時調用,打印一個終端消息:

import QtQuick 2.0

Item {
    width: 100; height: 100

    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.log("Click!")
        }
    }
}

Defining Signal Attributes

定義信號屬性

A signal may be defined for a type in C++ by registering a Q_SIGNAL of a class which is then registered with the QML type system. Alternatively, a custom signal for an object type may be defined in an object declaration in a QML document with the following syntax:

在C++中,對於將被註冊到QML類型系統的類,能夠經過 Q_SIGNAL 定義信號類型。在QML文檔中,能夠在對象聲明內使用以下的語法自定義信號類型:

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

Attempting to declare two signals or methods with the same name in the same type block is an error. However, a new signal may reuse the name of an existing signal on the type. (This should be done with caution, as the existing signal may be hidden and become inaccessible.)

在同一個類型塊內試圖定義2個同名的信號或方法是錯誤的。然而,新信號能夠重用類型的已存在信號名。(謹慎使用,由於已存在的方法可能被隱藏而且變得不可訪問。)

Here are three examples of signal declarations:

這裏是信號聲明的3個例子:

import QtQuick 2.0

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

If the signal has no parameters, the "()" brackets are optional. If parameters are used, the parameter types must be declared, as for the string and var arguments for the actionPerformed signal above. The allowed parameter types are the same as those listed under Defining Property Attributes on this page.

若是信號沒有參數,"()"是可選的。若是參數被使用,參數類型必須被聲明,像上面的 actionPerformed 信號的 string 和 var 參數。容許的參數類型和本頁列出的定義屬性特性是相同的。

To emit a signal, invoke it as a method. Any relevant signal handlers will be invoked when the signal is emitted, and handlers can use the defined signal argument names to access the respective arguments.

觸發信號,像調用方法同樣調用信號。信號被觸發時任何信號相關的處理將被調用,處理程序可使用信號已定義的參數訪問各自的參數。

Property Change Signals

QML types also provide built-in property change signals that are emitted whenever a property value changes, as previously described in the section on property attributes. See the upcoming section on property change signal handlers for more information about why these signals are useful, and how to use them.

QML類型也提供內建的屬性改變信號,在信號值改變時被觸發,正如前面章節所描述的屬性特徵。關於爲何這些信號是有用的而且如何使用他們。查看後續的屬性改變信號的處理。

Signal Handler Attributes

信號處理程序屬性

Signal handlers are a special sort of method attribute, where the method implementation is invoked by the QML engine whenever the associated signal is emitted. Adding a signal to an object definition in QML will automatically add an associated signal handler to the object definition, which has, by default, an empty implementation. Clients can provide an implementation, to implement program logic.

信號處理程序是特殊的方法屬性,不管什麼時候,關聯的信號被觸發時,該方法的實現被QML引擎調用。添加信號到對象定義將自動添加對應的信號處理程序,默認的是一個空的實現。用戶能夠提供一個實現去實現程序邏輯。

Consider the following SquareButton type, whose definition is provided in the SquareButton.qml file as shown below, with signals activated and deactivated:

考慮下面的的 SquareButton 類型,以下的 SquareButton.qml 中提供定義體,包含信號 activated 和 activated :

// SquareButton.qml
Rectangle {
    id: root

    signal activated(real xPosition, real yPosition)
    signal deactivated

    width: 100; height: 100

    MouseArea {
        anchors.fill: parent
        onPressed: root.activated(mouse.x, mouse.y)
        onRelased: root.deactivated()
    }
}

These signals could be received by any SquareButton objects in another QML file in the same directory, where implementations for the signal handlers are provided by the client:

這些信號應該被相同目錄下的另外一個QML文件中的 SquareButton 對象接收,用戶提供以下的信號處理程序實現:

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

See the Signal and Handler Event System for more details on use of signals.

更多的細節請查看查看信號和事件處理系統<Signal and Handler Event System>。

Property Change Signal Handlers

屬性改變信號的處理

Signal handlers for property change signal take the syntax form on<Property>Changed where <Property> is the name of the property, with the first letter capitalized. For example, although the TextInput type documentation does not document a textChanged signal, this signal is implicitly available through the fact that TextInput has a text property and so it is possible to write an onTextChanged signal handler to be called whenever this property changes:

屬性改變的信號的處理程序使用語法 on<Property>Changed ,<Property> 是屬性的名字而且第一個字母大寫。好比,雖然 TextInput 類型文檔沒有提供 textChanged 信號,可是經過 TextInput 有一個 text 屬性的事實讓這個信號是隱士可用的,而且寫一個 onTextChanged 信號處理程序(是可能的),不管什麼時候信號改變時被調用。

import QtQuick 2.0

TextInput {
    text: "Change this!"

    onTextChanged: console.log("Text has changed to:", text)
}

Method Attributes

方法屬性

A method of an object type is a function which may be called to perform some processing or trigger further events. A method can be connected to a signal so that it is automatically invoked whenever the signal is emitted. See Signal and Handler Event System for more details.

對象類型的方法是一個能夠被調用去執行一些處理或觸發後續事件的函數。方法能夠鏈接到信號以便信號被觸發時它能夠被自動調用。更多的細節請查看查看信號和事件處理系統<Signal and Handler Event System>。

Defining Method Attributes

定義方法屬性

A method may be defined for a type in C++ by tagging a function of a class which is then registered with the QML type system with Q_INVOKABLE or by registering it as a Q_SLOT of the class. Alternatively, a custom method can be added to an object declaration in a QML document with the following syntax:

類型的方法定義,能夠在C++中使用 Q_INVOKABLE 標註將被註冊到QML類型系統的類的函數,或者註冊該函數爲類的 Q_SLOT 。使用以下的語法在QML文檔內添加自定義方法到對象的聲明:

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

Methods can be added to a QML type in order to define standalone, reusable blocks of JavaScript code. These methods can be invoked either internally or by external objects.

方法被添加到QML類型以便定義獨立的可複用的 JavaScript 代碼快。方法能夠被內部調用,也能夠被外部對象調用。

Unlike signals, method parameter types do not have to be declared as they default to the var type.

不一樣於信號,方法的參數不是必須被定義的,參數默認是 var 類型。

Attempting to declare two methods or signals with the same name in the same type block is an error. However, a new method may reuse the name of an existing method on the type. (This should be done with caution, as the existing method may be hidden and become inaccessible.)

在同一個類型塊內試圖定義2個同名的方法或信號是錯誤的。然而,新方法能夠重用類型的已存在方法名。(謹慎使用,由於已存在的方法可能被隱藏而且變得不可訪問。)

Below is a Rectangle with a calculateHeight() method that is called when assigning the height value:

下面是一個帶有 calculateHeight() 方法的長方形,而且方法在分配高度值時被調用:

import QtQuick 2.0
Rectangle {
    id: rect

    function calculateHeight() {
        return rect.width / 2;
    }

    width: 100
    height: calculateHeight()
}

If the method has parameters, they are accessible by name within the method. Below, when the MouseArea is clicked it invokes the moveTo() method which can then refer to the received newX and newY parameters to reposition the text:

若是方法有參數,在方法內能夠經過名字訪問參數。以下,當 MouseArea 被點擊將調用 moveTo() 方法,方法能夠引用收到的 newX 和 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!"
    }
}

Attached Properties and Attached Signal Handlers

附加屬性和附加信號處理程序

Attached properties and attached signal handlers are mechanisms that enable objects to be annotated with extra properties or signal handlers that are otherwise unavailable to the object. In particular, they allow objects to access properties or signals that are specifically relevant to the individual object.

附加屬性和附加信號處理程序是一種使對象被解釋爲擴展屬性或信號處理程序(不然無效)的機制,特別地,這容許對象訪問與個別對象明確相關的屬性或者信號。

A QML type implementation may choose to create an attaching type with particular properties and signals. Instances of this type can then be created and attached to specific objects at run time, allowing those objects to access the properties and signals of the attaching type. These are accessed by prefixing the properties and respective signal handlers with the name of the attaching type.

QML的類型實現能夠選擇建立帶有特定屬性和信號的附加類型。在運行時(附加)類型實例能夠被建立而且附加到指定的對象,容許那些對象訪問附加類型的屬性和信號。這些被以附加類型名爲前綴的屬性和對應的信號處理程序訪問。

References to attached properties and handlers take the following syntax form:

附加屬性和處理程序使用以下的語法:

<AttachingType>.<propertyName>

<AttachingType>.on<SignalName>

For example, the ListView type has an attached property ListView.isCurrentItem that is available to each delegate object in a ListView. This can be used by each individual delegate object to determine whether it is the currently selected item in the view:

好比, 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"
    }
}

In this case, the name of the attaching type is ListView and the property in question is isCurrentItem, hence the attached property is referred to as ListView.isCurrentItem.

在這種狀況下,附加類型的名字是 ListView 而且界定的屬性是 isCurrentItem ,所以被附加的屬性是 ListView.isCurrentItem 的引用。

An attached signal handler is referred to in the same way. For example, the Component.onCompleted attached signal handler is commonly used to execute some JavaScript code when a component's creation process has been completed. In the example below, once the ListModel has been fully created, its Component.onCompleted signal handler will automatically be invoked to populate the model:

附加信號處理程序使用相同的引用方法。例如, Component.onCompleted 附加信號處理程序一般用來在組件的建立流程完成時執行 JavaScript 代碼。下面的例子,一旦 ListModel 被徹底建立,它的 Component.onCompleted 信號處理程序將自動被調用去生成模型:

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 }
}

Since the name of the attaching type is Component and that type has a completed signal, the attached signal handler is referred to as Component.onCompleted.

由於附加類型的名稱是 Component 而且有 completed 信號,因此附加信號處理程序是 Component.onCompleted 的引用。

A Note About Accessing Attached Properties and Signal Handlers

訪問附加屬性和信號處理程序的注意事項

A common error is to assume that attached properties and signal handlers are directly accessible from the children of the object to which these attributes have been attached. This is not the case. The instance of the attaching type is only attached to specific objects, not to the object and all of its children.

一個常見的錯誤是認爲附加屬性和信號處理對於那些已附加這些屬性的對象的子對象是直接可訪問的。事實並不是如此。附加類型的實例僅僅附屬於特定對象,不屬於對象和它的全部子對象。

For example, below is a modified version of the earlier example involving attached properties. This time, the delegate is an Item and the colored Rectangle is a child of that item:

例如,以下是以前的調用附加屬性的例子的一個修改版本。此次,代理是 Item 而且 colored Rectangle 是該 Item 的子對象:

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.
        }
    }
}

This does not work as expected because ListView.isCurrentItem is attached only to the root delegate object, and not its children. Since the Rectangle is a child of the delegate, rather than being the delegate itself, it cannot access the isCurrentItem attached property as ListView.isCurrentItem. So instead, the rectangle should access isCurrentItem through the root delegate:

如預期的那樣不工做,由於 ListView.isCurrentItem 僅僅是根代理對象的附加,並非它的子對象的附加。 Rectangle 是代理的子對象,不是代理自己,它不能以 ListView.isCurrentItem 的形式訪問 isCurrentItem 附加屬性。因此, Rectangle 應該經過根代理訪問 isCurrentItem 。

ListView {
    //....
    delegate: Item {
        id: delegateItem
        width: 100; height: 30

        Rectangle {
            width: 100; height: 30
            color: delegateItem.ListView.isCurrentItem ? "red" : "yellow"   // correct
        }
    }
}

Now delegateItem.ListView.isCurrentItem correctly refers to the isCurrentItem attached property of the delegate.

如今 delegateItem.ListView.isCurrentItem 正確的引用了代理的 isCurrentItem 附加屬性。

相關文章
相關標籤/搜索