In addition to the AppStudio QML components that are available for you to design the user interface of your app, you also have access to all of The Qt Company's own QML components. This topic describes the most useful components. For a full list of Qt QML types, refer to the Qt documentation.
The following are some of the most used QML types:
- Positioners
- Anchors
- Layouts
- Repeaters
- States
- Connections
Caution:
Differences have been observed in the display of user interface (UI) elements in AppStudio apps and samples while migrating from Qt 5.13.1 to Qt 5.15.2. Some differences include position, size, layout, color, cropping, wrapping, and font. Review the display of all UI elements of your apps. In some cases, you may need to change the nesting of your components; in other cases, additional or fewer properties may need to be defined. Because there is much flexibility in how UI elements are defined in QML, there are no set rules.
In release 5.15.2, Qt property types such as bool, string and int are strict and no longer support null or undefined values. If your app uses these types you must give consideration to how to support null or undefined values. Alternatively, you can use the property type var, which does allow null and undefined values, but also all other possible values.
Positioners
Positioners are container items that manage the positions of items in your user interface. Positioner types include row, column, grid, and flow. Organizing your items based on any of these allows you to arrange them in a regular layout that is well suited to resizable user interfaces. For example, organize your items in a grid, and when you view your app in a portrait orientation you may see a two-by-five matrix of items, but switch to landscape and it automatically rearranges your grid of items to best fit the screen, giving you a three-by-four matrix of items.
For more information on positioners, refer to the Qt documentation.
Anchors
Each item can be thought to have seven anchor points, and other items can be positioned in relation to these. These points are the top, bottom, left, right, horizontal center, vertical center, and baseline (the line on which text in the item is positioned). This is ideal for positioning items relative to each other to create dynamic user interfaces. The anchors remain even when the dimensions or locations of items change. Anchor margins can also be defined, specifying how much space should be left outside an item's anchor.
For more information on anchors, refer to the Qt documentation.
Layouts
To use Qt Quick Layouts, you must reference an additional module in your QML file, for example:
import QtQuick.Layouts 1.15
The three layouts are RowLayout, ColumnLayout, and GridLayout. Compared to rows, columns, and grids, using layouts allows more fine-grained control over item positioning. This includes the ability to specify the alignment of each item in the layout. GridLayouts also allow you to set separate column and row spacing, span items across rows and columns, and specify an individual grid cell for an item. Layouts can also be used to set the preferred maximum and minimum widths and heights, as well as the ability to fill width and height, for each item. This is especially useful when designing for dynamic or multiple displays. Layouts can also be mirrored, changing a left-to-right layout into a right-to-left layout.
Repeaters
A repeater object creates items from a template for use with positioners using data from a model. Combining repeaters and positioners is an effective way to lay out many items. A model can be one of the following:
- Number that indicates the number of delegates to be created by the repeater
- Free-form list data source—A ListModel
- String list
- Object list
The delegate provides a template defining each item instantiated by the repeater. A repeater delegate can access its index in the repeater as well as the model data relevant to the delegate.
For more information about repeaters, refer to the Qt documentation.
States
States can be used to show a different view or screen in an app. You can use them to show or hide elements based on the value of a property, to change anchoring, or to change parent objects. Based on the state, you can start, stop, or pause animations or execute scripts. Every item-based component has a state property and a default state. The default state is the empty string ("") and contains all initial property values. Setting the state property to an empty string loads the default state.
For more information about states, refer to the Qt documentation.
Connections
In Qt 5.15, there is a new syntax for connections. The previous method of creating an on<Signal> handler is deprecated, and now function syntax should be followed. The following is a warning message that you will receive when running an app using the previous connection syntax:
qrc:/qml/main.qml:277:5: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo (<arguments>) { ... }The following example shows how a connection was typically defined in Qt 5.13 and earlier:
Connections {
target: mouseArea
onPositionChanged: {
console.log( "onPositionChanged: ", mouse.x, mouse.y );
}
onPressedChanged: {
console.log( "onPressedChanged: ", mouseArea.pressed );
}
}
The following example shows how a connection should be defined in Qt 5.15 and later:
Connections {
target: mouseArea
function onPositionChanged(mouse) {
console.log( "onPositionChanged: ", mouse.x, mouse.y );
}
function onPressedChanged() {
console.log( "onPressedChanged: ", mouseArea.pressed );
}
}
Now that function syntax is used, you must ensure that any signal parameters are explicitly listed. If you omit any, the signal parameters will not be available by their name, and this can lead to undefined references in your code. For example, you must use function onPositionChanged(mouse) instead of onPositionChanged.
When listing the signal parameters, it’s recommended that you list all the parameters in the correct order using formal signal parameter names as the function parameter names. For example, use function onPositionChanged(mouse) and not function onPositionChanged(m).
If the signal is for a property change, you must explicitly name the object to access the property. For example, you must use mouseArea.pressed and not pressed.
For more information about connections, refer to the Qt documentation.