QML Dynamic Objects

From Qt Wiki
Revision as of 16:35, 14 January 2015 by Maintenance script (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

English

QML Dynamic Objects

Introduction

QML has a rich set of programmatic techniques for controlling visualization, for example making objects appear and disappear from the scene. These techniques can be classified in three groups.

  1. The techniques from the first group control a QML object property to hide and/or change how and object is rendered. For example, the opacity property is often used by developers to visually reflect the state of an item. We can use properties visible, z, and color:transparent in similar ways. Using these techniques objects are neither created nor destroyed, therefore there is little impact on memory usage.
  2. The second group applies transformations to objects: Move an object off the screen (assign negative values to x,y coordinates) or change the object’s shape. For instance, we may control object visualization through width and height properties. Again, minimal memory impact.
  3. The third group includes mechanisms based on dynamic loading of QML objects. These are QML constructs Loader and dynamic creation of objects. These techniques will impact memory usage.

There is no “right” and “wrong” here. Hidden objects continue to consume memory, but on the other hand they’re easily accessible through their IDs.

This article discusses dynamic creation of objects [doc.qt.nokia.com]. More information about Loader utilization is here [developer.qt.nokia.com].

Before we dig into the details, have a look at some examples of how these groups behave in the real world:

First and second group
Overlapping

Third group
Loader

The next snippet illustrates how width and height properties could be used to control visibility:

dynamicWidth.qml

You guessed already that top rectangle is constructed when QML file is loaded, but not visualized. It is because its width and height properties are not defined. We determine them later in MouseArea script block.

Creation of Dynamic QML Objects

The process of dynamic creating QML objects consists of two steps. Firstly, an object is created and secondly a newly created object is loaded. The process is performed in a JavaScript context only. In other words, we have some JavaScript methods, which could be invoked in a script block.

The dynamic object is normally formatted as a QML file or we may want to get it as a string. Our considerations are limited to the second case. For this case steps of creating and loading are combined in one step. The signature of the respective JavaScript method is as follows [doc.qt.nokia.com]:

The first argument in the method invocation is a string formatted as a QML file, for example:

We use single quotes for the QML string to avoid conflict with double quotes in color property definition.

The second argument is the ID of the QML item in which context the new object is created and loaded. That means that newly created object has as parent this context item. In invocation the context item ID is supplied as a variable name (no quotes are needed).

The third argument is a string used as a file name in error reporting in the Qt Creator IDE. For example if an error is encountered in loaded QML string it is reported as one in the file with filename name. In invocation filename as a string has to be surrounded by double quotes.

The function createQmlObject() is a method of the global QML Qt object [doc.qt.nokia.com].

Formally it is described as:

If you are tempted to use a Loader element from the QML string it will probably not work. It is because loading of an external file needs some time, but the method createQmlObject() returns not waiting for such operations. Here is a complete example of createQmlObject() method utilization:

dynamicObject.qml

Practically it is inconvenient to supply a long QML string in createQmlObject() call. We could define a string property and assign to it QML string as property value. This is demonstrated in the following example:

dynamicObjectTop.qml

Communication with Dynamic Objects

The dynamically created QML object is not accessible through its ID. We need other mechanisms for communication with dynamic objects and these are signals and QML signal objects connect () method. By communication we mean exchange of information between the caller (main QML file) and the callee (dynamically created QML file) and in both directions.

The next snippet shows that a property defined at the caller top level is visible (directly accessible) in the QML dynamic object:

property

dynamicObjectProperty.qml

In case we want to pass some information from QML string to the main file we define a signal, then connect it to a JavaScript method defined in the main QML file and finally emit the signal (in QML string):

signal

dynamicObjectConnect.qml

In the QML string we define the signal send, which invokes function fun1() defined in main QML. A parameter is passed also. And vice versa: in the main QML the signal forward is defined and emitted. It calls function fun2() defined in QML string.

Dynamic Objects Behavior – Nested Objects

Let us create an application with the following functionality:
1. The user enters some text in a QML TextInput element;
2. The entered text is displayed in a window;
3. The user is asked to confirm the entered text in a dialog window;

input

The new point here is that from a dynamic object we want to create and load a next dynamic object.

dynamicUseCase.qml

Some fragments of the above code need more explanation as they implement several rules of QML dynamic objects. In the first place, a dynamic QML object (rectangle abc) could contain a nested QML string – rectangle nested. As you see, the nested objects are in the same name space and this is used when we design the application layout – it is applied bounding of properties values. Moreover, the nested objects are executed in the context of the main QML file and they use properties from the main application space.

To invoke the first dynamic object (rectangle abc) we use onAccepted signal generated after you enter the text in the QML TextInput field and hit <Enter>. The entered text is displayed in the rectangle abc. When you click on this rectangle, following onClicked signal, the nested object (rectangle nested) is rendered.

Destroying Dynamic Objects

Analyzing the above code samples you probably asked yourself already how one could close dynamically created QML objects. To release (delete) a dynamically created QML object you could use destroy() method from within a JavaScript context. The method is called as member of newly created dynamic object. For example, considering our last code snippet, we call: dynamicObject.destroy(). The destroy() method has a parameter that supplies the time delay before the dynamic object will be destroyed. It is measured in milliseconds with a default value of zero.
In the file dynamicUseCase.qml you have an commented section (at the file bottom) that experiments with destroy() method. Uncomment this section and call to release() function in onAccepted script block.

Notes:
1. The .qml files used in the discussions above could be downloaded here [bit.ly].
2. The code samples were tested in a desktop environment – Windows 7, Qt Creator 2.4.1 (based on Qt 4.7.4).

Categories: