1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in a
** written agreement between you and Nokia.
**
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of this
** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page qdeclarativedynamicobjects.html
\title Dynamic Object Management
QML provides a number of ways to dynamically create and manage QML objects.
The \l{Loader}, \l{Repeater}, \l{ListView}, \l{GridView} and \l{PathView} elements
all support dynamic object management. Objects can also be created and managed
from C++, and this is the preferred method for hybrid QML/C++ applications
(see \l{Using QML in C++ Applications}).
QML also supports the dynamic creation of objects from within JavaScript
code. This is useful if the existing QML elements do not fit the needs of your
application, and there are no C++ components involved.
See the {declarative/toys/dynamicscene}{Dynamic Scene example} for a demonstration
of the concepts discussed on this page.
\section1 Creating Objects Dynamically
There are two ways to create objects dynamically from JavaScript. You can either call
\l {QML:Qt::createComponent()}{Qt.createComponent()} to create
a component which instantiates items, or use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}
to create an item from a string of QML.
Creating a component is better if you have a predefined
item, and you want to create dynamic instances of that item; creating an item from
a string of QML is useful when the item QML itself is generated at runtime.
If you have a component specified in a QML file, you can dynamically load it with
the \l {QML:Qt::createComponent()}{Qt.createComponent()} function on the \l{QML Global Object}.
This function takes the URL of the QML file as its only argument and returns
a component object which can be used to create and load that QML file.
Once you have a component you can use its \l {Component::createObject()}{createObject()} method to create an instance of
the component. This function takes exactly one argument, which is the parent for the new item. Since graphical items will
not appear on the scene without a parent, it is recommended that you set the parent this way. However, if you wish to set
the parent later you can safely pass null to this function.
Here is an example. Here is a \c Sprite.qml, which defines a simple QML component:
\snippet doc/src/snippets/declarative/Sprite.qml 0
Our main application file, \c main.qml, imports a \c componentCreation.js JavaScript file
that will create \c Sprite objects:
\snippet doc/src/snippets/declarative/createComponent.qml 0
Here is \c componentCreation.js. Remember that QML files that might be loaded
over the network cannot be expected to be ready immediately:
\snippet doc/src/snippets/declarative/componentCreation.js 0
\codeline
\snippet doc/src/snippets/declarative/componentCreation.js 1
If you are certain the files will be local, you could simplify to:
\snippet doc/src/snippets/declarative/componentCreation.js 2
Notice that once a \c Sprite object is created, its parent is set to \c appWindow (defined
in \c main.qml). After creating an item, you must set its parent to an item within the scene.
Otherwise your dynamically created item will not appear in the scene.
When using files with relative paths, the path should
be relative to the file where \l {QML:Qt::createComponent()}{Qt.createComponent()} is executed.
If the QML component does not exist until runtime, you can create a QML item from
a string of QML using the \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()} function, as in the following example:
\snippet doc/src/snippets/declarative/createQmlObject.qml 0
The first argument is the string of QML to create. Just like in a new file, you will need to
import any types you wish to use. For importing files with relative paths, the path should
be relative to the file where the item in the second argument is defined. Remember to set the parent after
creating the item. The second argument is another item in the scene, and the new item is created
in the same QML Context as this item. The third argument is the file path associated with this
item, which is used for error reporting.
\section1 Maintaining Dynamically Created Objects
When managing dynamically created items, you must ensure the creation context
outlives the created item. Otherwise, if the creation context is destroyed first,
the bindings in the dynamic item will no longer work.
The actual creation context depends on how an item is created:
\list
\o If \l {QML:Qt::createComponent()}{Qt.createComponent()} is used, the creation context
is the QDeclarativeContext in which this method is called
\o If \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}
if called, it is the context of the item used as the second argument to this method
\o If a \c {Component{}} item is defined and \l {Component::createObject()}{createObject()}
is called on that item, it is the context in which the \c Component is defined
\endlist
Also, note that while dynamically created objects may be used the same as other objects, they
do not have an id in QML.
\section1 Deleting Objects Dynamically
In many user interfaces, it is sufficient to set an item's opacity to 0 or
to move the item off the screen instead of deleting the item. If you have
lots of dynamically created items, however, you may receive a worthwhile
performance benefit if unused items are deleted.
Note that you should never manually delete items that were dynamically created
by QML elements (such as \l Loader). Also, you should generally avoid deleting
items that you did not dynamically create yourself.
Items can be deleted using the \c destroy() method. This method has an optional
argument (which defaults to 0) that specifies the approximate delay in milliseconds
before the object is to be destroyed. This allows you to wait until the completion of
an animation or transition. An example:
\snippet doc/src/snippets/declarative/dynamicObjects.qml 0
Here, \c Rectangle objects are destroyed one second after they are created, which is long
enough for the \c NumberAnimation to be played before the object is destroyed.
*/
|