QML Concepts and SyntaxThis chapter covers the basic syntax of the QML language through the use of examples, introducing the concepts behind the language and the terminology used in the reference documentation. [Missing image declarative-qmlintro-basic-syntax.png] The following example shows the basic syntax of QML. When opened in the Qt QML Viewer tool, the output displayed should match the image shown on the right: a light blue rectangle. In this example, we import the features defined by Qt Quick 1.0, and we declare and create a single rectangle with width, height and color. Let's take a look at the main points of the language introduced by this simple example. Importing ModulesThe import statement imports the QtQuick module, which contains all of the standard QML Elements. Without this import statement, the Rectangle and other elements would not be available. A specific version of a module is imported. This guarantees that the elements imported when the application is run by the user match those used by the developer when the application was written, ensuring that they have the expected behavior. ElementsThe rectangle in the above example is specified by the Rectangle element. When we declare objects like this, we write the element's type followed by a pair of braces in between which additional data can be defined for the object, such as its property values and any child objects. [Missing image declarative-qmlintro-elements1.png] Here, we create two elements: a rectangle with an image inside it. We say that the rectangle is the parent element and the image is its child. Since the rectangle does not have a parent element, it is a top level element. The position of each element in the user interface is defined relative to the position of its parent, except for the top level element whose position is always the top-left corner of the screen. QML files can contain multiple elements, but only one can be a top level element. [Missing image declarative-qmlintro-elements2.png] In this example, we can define as many elements inside the rectangle as we like, but we cannot define other top level elements. All the additional elements are defined inside the light blue rectangle. Note: In the QML documentation, we refer to elements, items and components, often interchangeably.
For now, we will refer to elements and items. Components are discussed in detail later in this guide. A list of the most common elements is described on the QML Basic Elements page. A full list can be found on the QML Elements page. PropertiesA QML element usually has various properties that help define the element. For example, all items have the x and y properties that define the position of the item relative to its parent item (or the screen's origin) and width and height properties that define its dimensions. All simple properties have names that begin with a lower case letter. Setting PropertiesProperties are specified with a property: value syntax. In the above example, we can see the Image object has a property named source, which has been assigned the value "pics/logo.png". The property and its value are separated by a colon. Properties can be specified one-per-line: Rectangle { width: 100 height: 100 } or you can put multiple properties on a single line: Rectangle { width: 100; height: 100 } When multiple property-value pairs are specified on a single line, they must be separated by a semicolon. Basic Property TypesQML supports properties of many types (see QML Basic Types). The basic types include int, real, bool, string and color. Item { x: 10.5 // a 'real' property state: "details" // a 'string' property focus: true // a 'bool' property // ... } QML properties are what is known as type-safe. That is, they only allow you to assign a value that matches the property type. For example, the x property of item is a real, and if you try to assign a string to it you will get an error. Item { x: "hello" // illegal! } Property values are dynamic, responding to changes in the user interface. See the Property Change Notifications section for information on the different ways to define properties, bind them together and react to changes. Grouped PropertiesSome elements contain a set of related properties that form a logical group; these use a "dot" or grouped notation to show this. The Text item is one such item that uses groups of properties to describe the font used to display text. Grouped properties can be written like this: or like this: In the element documentation, grouped properties are shown using the "dot" notation. List PropertiesSome properties contain lists of elements, such as State, Item or Transition. For example, the states property is used like this: Item { states: [ State { name: "stop" }, State { name: "go" } ] } The list is enclosed in square brackets, with a comma separating the list elements. In cases where you are only assigning a single element to a list, you can omit the square brackets: Item { states: State { name: "stop" } } Elements in the list can be accessed by index. See the list type documentation for more details about list properties and their available operations. ExpressionsJavaScript expressions can be used to assign property values. For example: Item { width: 100 * 3 height: 50 + 22 } These expressions can include references to other objects and properties, in which case a binding is established: when the value of the expression changes, the property to which the expression is assigned is automatically updated to the new value. For example: [Missing image declarative-qmlintro-property-binding1.png] Here, the child Rectangle item's width property is set relative to the width of its parent. Whenever the parent's width changes, the width of the Rectangle is automatically updated. This uses the special parent property to refer to a parent item, which we explore in the next section. This is useful for relating the size of one element to another, so that changes to the sizes of elements in the design, or at run-time, will be taken into account. Property binding works with all types of properties, not just those related to the size of an element. Object IdentifiersEach object can be given a special id value that allows the object to be identified and referred to by other objects. An id must begin with a lower-case letter or an underscore, and cannot contain characters other than letters, numbers and underscores. For example, below we define a Text element and a Rectangle element as children of a Column element. The Text object has an id value of textElement. The Rectangle object defines its width property to be the same as that of the Text object by referring to textElement.width: [Missing image declarative-qmlintro-object-identifiers.png] An object can be referred to by its id from anywhere within the component in which it is declared. Therefore, an id value must always be unique within a single component. This means that a single QML file should only contain one place where a particular id value is defined. The id value is a special value for a QML object and should not be thought of as an ordinary object property; for example, it is not possible to access textElement.id in the above example. Once an object is created, its id cannot be changed. Note: The parent value is a special identity that each element can use to refer to its parent item. For most simple user interfaces containing a few display items, the parent of an item will be the enclosing element in the QML file that contains it. However, when we look at more complex ways to arrange and display items, we will find that this is not always the case. CommentsCommenting in QML is similar to JavaScript.
Comments are ignored by the QML engine. They are useful for explaining what you are doing; for referring back to at a later date, or for others reading your QML files. Comments can also be used to prevent the execution of code, which is sometimes useful for tracking down problems. In the above example, the Text element will have normal opacity, since the line containing the opacity property has been turned into a comment. Responding to ChangesUser interfaces created using QML contain items such as Rectangle, Image and Text to display content, but they can also contain items that accept user input, such as TextInput and MouseArea. When the user interacts with these items, they emit signals to inform other components of any change. These signals can be received by the items themselves; this is the main way to create items that respond to the user. Signal HandlersSignal handlers allow JavaScript code to be executed in response to a signal. For example, the MouseArea element has an onClicked handler that can be used to respond to a mouse click. Below, we use this handler to print a message whenever the mouse is clicked: All signal handlers begin with "on". Some signal handlers include an optional parameter. For example the MouseArea onPressed signal handler has a mouse parameter that contains information about the mouse press. This parameter can be referred to in the JavaScript code, as below: Property Change NotificationsWhen a property changes value, it can send a signal to notify others of this change. To receive these signals, simply create a signal handler named with an on<Property>Changed syntax. For example, the TextInput element has a text property. When this property changes, the textChanged signal is emitted. We can monitor this property for changes with the onTextChanged handler.
The following code shows this in practice: [Missing image declarative-qmlintro-property-change1.png] When the user modifies the text, the expression assigned to the textChanged handler will be evaluated. In this example, the text changes color when this happens. Similarly, the Rectangle element has width and color properties. Below, we have a Rectangle element that has defined two signal handlers, onWidthChanged and onColorChanged, which will automatically be called whenever these properties are modified: Rectangle { width: 100; height: 100 onWidthChanged: console.log("Width has changed to:", width) onColorChanged: console.log("Color has changed to:", color) } These cause the new values of these properties to be written to the console, which can be useful for debugging purposes. Attached PropertiesSome elements attach properties to other elements. This is used in cases where one element needs to access features of another, but does not inherit properties to access those features. Attached Properties are of the form <Type>.<property> where <Type> is the type of the element that attaches <property>. An example of attached properties in use involves the Keys element which attaches properties for handling key presses to any item. For example: [Missing image declarative-qmlintro-attached-properties.png] The Keys properties are not defined by the Item element. They are defined separately and attached to the item. Attached properties are also used by delegates to reference information about the view they are used in. For example, the ListView element attaches the ListView.isCurrentItem property to each delegate it creates: [Missing image declarative-qmlintro-attached-properties-view.png] In effect, by attaching this property, ListView provides an interface that lets the delegate access information about the current item in the view it appears in. The use of attached properties will be covered in more depth later in this guide. |