On this page

C

QML object attributes

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 different kinds of object attributes, which are described in the following sections.

Attributes in object declarations

An object declaration in a QML document defines a new type. It also declares an object hierarchy that will be instantiated when you create an instance of that defined type.

A QML object type definition can also include any of the following attribute types:

  • the id attribute
  • property attributes
  • signal attributes
  • signal handler attributes
  • method attributes
  • attached properties and attached signal handler attributes
  • enumeration attributes

These attributes are discussed in detail below.

id attribute

A QML object type can have a maximum of one id attribute. This attribute is provided by the language itself, and it cannot be redefined or overridden by any QML object type.

A value assigned to the id attribute of an object instance enables other objects to identify and refer to that object instance. This id must begin with a lower-case letter or an underscore, and cannot contain characters other than letters, numbers, and underscores.

The following example defines a TextInput object and a Text object. The TextInput object's id value is "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 these items will display the same text:

import QtQuick

Column {
    width: 200; height: 200

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

    Text { text: myTextInput.text }
}

You can refer to an object using its id from anywhere within the QML context in which it is created. Therefore, an id value must always be unique within its context.

Once you create an instance of the object, you cannot change its id attribute. While it may look like any other property, the id attribute is not an ordinary property attribute, and special semantics apply to it; for example, you cannot access myTextInput.id in the earlier example.

Property attributes

An object's property is an attribute that you can either set to 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 defined its property as read only.

Defining property attributes

The public members of a class declaration that you export are available as component properties if they are of Qul::Property<T> type. Here T describes the property's C++ type and is mapped to a corresponding QML type.

Note: Every type T that does not have a built-in comparison operator must be provided with a user-defined operator==.

The properties that you define in this way behave like built-in properties. In particular, you can assign bindings in QML and use as a data source in other bindings.

The following example demonstrates how to use properties. Define a property in C++:

struct MyData : public Qul::Object
{
    Qul::Property<int> val;
    void update(int x)
    {
        // can get and set property values from C++
        val.setValue(x);
    }
};

And use it in QML:

Item {
    Item {
        // can bind QML property to exported property
        x: mydata_x.val
        color: "red"
        width: 50
        height: 50
    }
    MyData {
        id: mydata_x
        val: 100
    }
    MyData {
        id: mydata_width
        // can bind exported property
        val: parent.width
    }
    Component.onCompleted: {
        mydata_x.update(200);
        console.log(mydata_width.val);
    }
}

Note: Calling Qul::Property::setValue does not request Qt Quick Ultralite engine update. Event queue is needed if there are no QML animations or timers running. Repainting can be triggered by using an event queue as shown below.

struct MySingleton : public Qul::Singleton<MySingleton>
{
    Qul::Property<int> val;

    // function that is called only from the C++ code
    void update(int value);
};

class MyEventQueue : public Qul::EventQueue<int>
{
    void onEvent(const int &value) override
    {
        // set property value in the event handler
        MySingleton::instance().val.setValue(value);
    }
};

void MySingleton::update(int value)
{
    static MyEventQueue myEventQueue;
    myEventQueue.postEvent(value);
}

For more information, see using properties with Qt Quick Ultralite.

Defining custom property attributes

Alternatively, you can also define a custom property of an object type using the following syntax:

[readonly] property <propertyType> <propertyName>

This allows the object to either 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 readonly keyword is optional, and it modifies the semantics of the property. See read-only properties for more information.

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.

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

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 value types can be used as custom property types. For example, these are all valid property declarations:

Item {
    property int someNumber
    property string someString
}

Note: Enumeration values are simply whole number values and can be referred to using the int type.

Some value types that are provided by the QtQuick module cannot be used as property types unless you import the module. See QML value types for more details.

Additionally, you can use any QML object type as a property type. For example:

property Item someItem
property Rectangle someRectangle

This applies to custom QML types as well. If you define a QML type in the ColorfulButton.qml file, a property of ColorfulButton type is valid.

Assigning values to property attributes

You can assign value to an object instance property using either of the following ways:

  • a value assignment on initialization
  • an imperative value assignment

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

Value assignment on initialization

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

<propertyName> : <value>

You can assign an initialization value with the property definition in an object declaration. In that case, use the following syntax for the property definition:

property <propertyType> <propertyName> : <value>

The following is an example of property value initialization:

import QtQuick

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

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

[<objectId>.]<propertyName> = value

An example of imperative value assignment follows:

import QtQuick

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

Note: Qt for MCUs supports only a limited subset of JavaScript. For more information, see JavaScript environment for Qt Quick Ultralite applications.

Static values and binding expression values

As mentioned earlier, there are two kinds of values that you can assign to a property: static values and binding expressions. The latter are also known as property bindings.

KindSemantics
Static valueA constant value which does not depend on other properties.
Binding expressionA JavaScript expression which describes a property's relationship with other properties. The variables in this expression are 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.

Note: Qt for MCUs supports only a limited subset of JavaScript. For more information, see JavaScript environment for Qt Quick Ultralite applications.

The following example shows how to assign these two types of values to properties:

import QtQuick

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

Type safety

Properties are type-safe, which means you can only assign a value that matches the property's type.

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

property int volume: "four"  // generates an error; the code will not compile

Likewise, if you assign a value of different type at runtime, it will generate an error.

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. For example, even though properties of the color type store colors and not strings, you are able to assign the "red" string to a color property without an error.

See all QML types for a list of the property types that are supported by default.

Special property types

Object list property attributes

You can assign a list of QML object-type value to a list type property. The syntax for defining an object list value is a comma-separated list surrounded by square brackets:

[ <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:

import QtQuick

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

If the list contains a single item, you can omit the square brackets:

import QtQuick

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

Use the following syntax to assign a list type value to a property in an object declaration:

property list<<ObjectType>> propertyName

Similar to other property declarations, use the following syntax to initialize a property while declaring the object:

property list<<ObjectType>> propertyName: <value>

An example of list property declaration follows:

import QtQuick

Rectangle {
    // declaration without initialization
    property list<Rectangle> siblingRects

    // declaration with initialization
    property list<Rectangle> childRects: [
        Rectangle { color: "red" },
        Rectangle { color: "blue"}
    ]
}
Grouped properties

In some cases properties contain a logical group of sub-property attributes. You can assign values to these sub-property attributes using either the dot notation or the group notation.

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

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

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

Grouped property types are types which have subproperties. If a grouped property type is an object type (as opposed to a value type), the property that holds it must be read-only. This is to avoid replacing the object the subproperties belong to.

Property aliases

Property aliases are properties that hold a reference to another property. Unlike an ordinary property definition, which allocates a new and 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:

property alias <name>: <alias reference>

Unlike an ordinary property, an alias has the following restrictions:

  • It can only refer to an object, or an object's property, that is within the scope of the type that declares the alias property.
  • It cannot contain arbitrary JavaScript expressions.
  • It cannot refer to objects declared outside the scope of its type.
  • An alias reference is required at declaration, unlike the optional default value for ordinary properties.
  • It cannot refer to attached properties.
  • It cannot refer to properties inside a hierarchy with depth greater than two.

In the following example, the Button type with a buttonText aliased property is connected to the text object of the Text child:

// Button.qml
import QtQuick

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:

Button { buttonText: "Click Me" }

Here, modifying buttonText directly modifies the textItem.text value; it does not change some other value to update textItem.text. Without the alias, changing buttonText would not update the displayed text because property bindings are unidirectional: textItem.text affects buttonText, but not vice versa.

Property aliases and types

Property aliases cannot have explicit type specifications. The type of a property alias is the declared type of the property or object it refers to. Therefore, if you create an alias to an object using its id, the extra properties are not be accessible through the alias:

// MyItem.qml
Item {
    property alias inner: innerItem

    Item {
        id: innerItem
        property int extraProperty
    }
}

You cannot initialize inner.extraProperty from outside of this component, as inner is only an Item:

// main.qml
MyItem {
    inner.extraProperty: 5 // fails
}

However, if you extract the inner object into a separate QML document (.qml), you can instantiate it and access all its properties through the alias:

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

Read-only properties

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

readonly property <propertyType> <propertyName> : <value>

Read-only properties must be assigned either a static value or a binding expression on initialization.

Note: After a read-only property is initialized, you cannot change its static value or binding expression anymore.

In the following example, the code in the Component.onCompleted block is invalid:

Item {
    readonly property int someNumber: 10

    Component.onCompleted: someNumber = 20  // TypeError: Cannot assign to read-only 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
}

This is commonly referred to as "on" syntax.

It is important to note that the syntax mentioned earlier is an object declaration that will instantiate an object, which acts on a pre-existing property.

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

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.

An object can be notified through a signal handler whenever 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.

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:

import QtQuick

Item {
    width: 100; height: 100

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

Defining signal attributes

Public members of type Qul::Signal<Fn> are translated to signals on the QML component.

The template argument Fn must be a function type that describes the signal's parameter types. As usual, these types are mapped to the matching QML types. Similarly, the parameter names used in Fn becomes a QML signal's parameter names.

The following code demonstrates how use signals:

struct MyItem : public Qul::Object
{
    Qul::Signal<void(int sigValue)> triggered;
    void callTriggered() { triggered(42); }
};


Item {
    MyItem {
        id: myitem
        onTriggered: console.log(sigValue);
    }
    Component.onCompleted: myitem.callTriggered()
}

Property change signals

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

Signal handler attributes

Signal handlers are a special method attributes, 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. To implement program logic, clients can provide an implementation.

Consider the following SquareButton type (defined in SquareButton.qml) with the activated and deactivated signals:

// SquareButton.qml
Rectangle {
    id: root

    signal activated(xPosition: real, yPosition: real)
    signal deactivated

    property int side: 100
    width: side; height: side

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

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:

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

Signal handlers don't have to declare their parameter types because the signal already specifies them.

For more details on the use of signals, see signal and handler event system.

Property change signal handlers

Signal handlers for property change signals take the syntax form on<Property>Changed, where <Property> is the name of the property, with the first letter capitalized. For example, the TextInput type does not document a textChanged signal, but this signal is implicitly available because TextInput has a text property. This means that you can use the onTextChanged signal handler to react to the text property changes:

import QtQuick

TextInput {
    text: "Change this!"

    onTextChanged: console.log(`Text has changed to: ${text}`)
}

Method attributes

A method of an object type is a function that you may call either to process something or to 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.

Defining method attributes

Qt for MCUs also offers C++ functions by default for objects and singletons that are available in QML. For more information, see using functions with Qt Quick Ultralite.

Alternatively, a custom method can be added to an object declaration in a QML document with the following syntax:

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

Methods can be added to a QML type to define standalone and reusable blocks of JavaScript code. These methods can be invoked either by internal or by external objects. Also, the method parameter types must be declared.

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, however, as the existing method may be hidden and become inaccessible.

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

import QtQuick

Rectangle {
    id: rect

    function calculateHeight(): real {
        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:

import QtQuick

Item {
    width: 200; height: 200

    MouseArea {
        anchors.fill: parent
        onClicked: label.moveTo(mouse.x, mouse.y)
    }

    Text {
        id: label

        function moveTo(newX: real, newY: real) {
            label.x = newX;
            label.y = newY;
        }

        text: "Move me!"
    }
}

Attached properties and attached signal handlers

Attached properties and signal handlers are mechanisms that enable objects to be annotated with extra properties or signal handlers, which 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 in C++ with particular properties and signals. You can create and attach instances of this type 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.

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

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

For example, the PathView type has an attached property PathView.isCurrentItem that is available to each delegate object in a PathView. Each delegate instance uses this property to determine whether it is the currently selected item in the view:

import QtQuick

PathView {
    width: 240; height: 320
    model: 3
    delegate: Rectangle {
        width: 100; height: 30
        color: PathView.isCurrentItem ? "red" : "yellow"
    }
}

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

The Component.onCompleted can be used to do various initialization tasks, such as setting values or calling functions:

// main.qml

Rectangle {
    id: root

    Component.onCompleted: {
        if(Qt.uiLanguage == "") {
            Qt.uiLanguage = "en_GB"
        }
    }
}

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.

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.

The following example is a modified version of the earlier example involving attached properties. This time, the delegate is an Item and the colored Rectangle is its child:

import QtQuick

PathView {
    width: 240; height: 320
    model: 3
    delegate: Item {
        width: 100; height: 30

        Rectangle {
            width: 100; height: 30
            color: PathView.isCurrentItem ? "red" : "yellow" // WRONG! This won't work.
        }
    }
}

This does not work as expected because PathView.isCurrentItem is attached to the root delegate object only, and not its children. As the Rectangle is a child of the delegate, it cannot access the isCurrentItem attached property as PathView.isCurrentItem. Instead, the rectangle should access isCurrentItem through the root delegate:

PathView {
    model: 4
    pathItemCount: 3
    path: Path {
        startX: 120; startY: 100
        PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
        PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 }
    }

    delegate: Item {
        id: delegateItem
        width: 100; height: 30

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

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

Enumeration attributes

Enumerations provide a fixed set of named choices. They can be declared in QML using the enum keyword:

// MyText.qml
Text {
    enum TextType {
        Normal,
        Heading
    }
}

As shown above, enumeration types such as TextType, and values such as Normal must begin with an uppercase letter.

You can refer to the enum values using either <Type>.<EnumerationType>.<Value> or <Type>.<Value> syntax.

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

For more information on enumeration usage in QML, see enumeration.

Available under certain Qt licenses.
Find out more.