Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
dynamicobjectcreation.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2017 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\page qtqml-javascript-dynamicobjectcreation.html
6
\title Dynamic QML Object Creation from JavaScript
7
\brief instantiating and managing QML objects from JavaScript
8
9
QML supports the dynamic creation of objects from within JavaScript. This is
10
useful to delay instantiation of objects until necessary, thereby improving
11
application startup time. It also allows visual objects to be dynamically
12
created and added to the scene in reaction to user input or other events.
13
14
\section1 Creating Objects Dynamically
15
16
There are two ways to create objects dynamically from JavaScript. You can
17
either call \l {QtQml::Qt::createComponent()}{Qt.createComponent()} to
18
dynamically create a \l Component object, or use \l{QtQml::Qt::createQmlObject()}
19
{Qt.createQmlObject()} to create an object from a string of QML. Creating a
20
component is better if you have an existing component defined in a QML document
21
and you want to dynamically create instances of that component. Otherwise,
22
creating an object from a string of QML is useful when the object QML itself is
23
generated at runtime.
24
25
26
\section2 Creating a Component Dynamically
27
28
To dynamically load a component defined in a QML file, call the
29
\l {QtQml::Qt::createComponent()}{Qt.createComponent()} function in the
30
\l {QmlGlobalQtObject}{Qt object}.
31
This function takes the URL of the QML file as its only argument and creates
32
a \l Component object from this URL.
33
34
Once you have a \l Component, you can call its \l {Component::createObject()}
35
{createObject()} method to create an instance of the component. This function
36
can take one or two arguments:
37
\list
38
\li The first is the parent for the new object. The parent can be a graphical
39
object (i.e. of the \l Item type) or non-graphical object (i.e. of the
40
\l QtObject or C++ QObject type). Only graphical objects with graphical
41
parent objects will be rendered to the \l {Qt Quick} visual canvas. If you wish
42
to set the parent later you can safely pass \c null to this function.
43
\li The second is optional and is a map of property-value pairs that define
44
initial any property values for the object. Property values specified by
45
this argument are applied to the object before its creation is finalized,
46
avoiding binding errors that may occur if particular properties must be
47
initialized to enable other property bindings. Additionally, there are
48
small performance benefits when compared to defining property values and
49
bindings after the object is created.
50
\endlist
51
52
Here is an example. First there is \c Sprite.qml, which defines a simple QML component:
53
54
\snippet qml/Sprite.qml 0
55
56
Our main application file, \c main.qml, imports a \c componentCreation.js
57
JavaScript file that will create \c Sprite objects:
58
59
\snippet qml/createComponent.qml 0
60
61
Here is \c componentCreation.js. Notice it checks whether the component
62
\l{Component::status}{status} is \c Component.Ready before calling
63
\l {Component::createObject()}{createObject()} in case the QML file is loaded
64
over a network and thus is not ready immediately.
65
66
\snippet qml/componentCreation.js vars
67
\codeline
68
\snippet qml/componentCreation.js func
69
\snippet qml/componentCreation.js remote
70
\snippet qml/componentCreation.js func-end
71
\codeline
72
\snippet qml/componentCreation.js finishCreation
73
74
If you are certain the QML file to be loaded is a local file, you could omit
75
the \c finishCreation() function and call \l {Component::createObject()}
76
{createObject()} immediately:
77
78
\snippet qml/componentCreation.js func
79
\snippet qml/componentCreation.js local
80
\snippet qml/componentCreation.js func-end
81
82
Notice in both instances, \l {Component::createObject()}{createObject()} is
83
called with \c appWindow passed as the parent argument, since the dynamically
84
created object is a visual (Qt Quick) object. The created object will become a
85
child of the \c appWindow object in \c main.qml, and appear in the scene.
86
87
When using files with relative paths, the path should
88
be relative to the file where \l {QtQml::Qt::createComponent()}
89
{Qt.createComponent()} is executed.
90
91
To connect signals to (or receive signals from) dynamically created objects,
92
use the signal \c connect() method. See
93
\l{Signal and Handler Event System#Connecting Signals to Methods and Signals}
94
{Connecting Signals to Methods and Signals} for more information.
95
96
It is also possible to instantiate components without blocking via the
97
\l {Component::incubateObject()}{incubateObject()} function.
98
99
\section2 Creating an Object from a String of QML
100
101
\warning Creating objects from a string of QML is extremely slow since the engine has to compile the
102
passed QML string every time you do it. Furthermore, it's very easy to produce invalid QML when
103
programmatically constructing QML code. It's much better to keep your QML components as separate
104
files and add properties and methods to customize their behavior than to produce new components by
105
string manipulation.
106
107
If the QML is not defined until runtime, you can create a QML object from
108
a string of QML using the \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}
109
function, as in the following example:
110
111
\snippet qml/createQmlObject.qml 0
112
113
The first argument is the string of QML to create. Just like in a new file,
114
you will need to import any types you wish to use. The second argument is the
115
parent object for the new object, and the parent argument semantics which apply
116
to components are similarly applicable for \c createQmlObject().
117
The third argument is the file path to associate with the new object; this is
118
used for error reporting.
119
120
If the string of QML imports files using relative paths, the path should be
121
relative to the file in which the parent object (the second argument to the
122
method) is defined.
123
124
\important When building static QML applications,
125
QML files are scanned to detect import dependencies. That way, all
126
necessary plugins and resources are resolved at compile time.
127
However, only explicit import statements are considered (those found at
128
the top of a QML file), and not import statements enclosed within string literals.
129
To support static builds, you therefore need to ensure that QML files
130
using \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()},
131
explicitly contain all necessary imports at the top of the file in addition
132
to inside the string literals.
133
134
\section1 Maintaining Dynamically Created Objects
135
136
When managing dynamically created objects, you must ensure the creation context
137
outlives the created object. Otherwise, if the creation context is destroyed
138
first, the bindings and signal handlers in the dynamic object will no longer work.
139
140
The actual creation context depends on how an object is created:
141
142
\list
143
\li If \l {QtQml::Qt::createComponent()}{Qt.createComponent()} is used, the
144
creation context is the QQmlContext in which this method is called
145
\li If \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()} is called, the
146
creation context is the context of the parent object passed to this method
147
\li If a \c {Component{}} object is defined and \l {Component::createObject()}
148
{createObject()} or \l {Component::incubateObject()}{incubateObject()} is
149
called on that object, the creation context is the context in which the
150
\c Component is defined
151
\endlist
152
153
Also, note that while dynamically created objects may be used the same as other
154
objects, they do not have an id in QML.
155
156
157
\section1 Deleting Objects Dynamically
158
159
In many user interfaces, it is sufficient to set a visual object's opacity to 0
160
or to move the visual object off the screen instead of deleting it. If you have
161
lots of dynamically created objects, however, you may receive a worthwhile
162
performance benefit if unused objects are deleted.
163
164
Note that you should never manually delete objects that were dynamically
165
created by convenience QML object factories (such as \l Loader and
166
\l Repeater). Also, you should avoid deleting objects that you did not
167
dynamically create yourself.
168
169
Items can be deleted using the \c destroy() method. This method has an optional
170
argument (which defaults to 0) that specifies the approximate delay in
171
milliseconds before the object is to be destroyed.
172
173
Here is an example. The \c application.qml creates five instances of the
174
\c SelfDestroyingRect.qml component. Each instance runs a NumberAnimation,
175
and when the animation has finished, calls \c destroy() on its root object to
176
destroy itself:
177
178
\table
179
\row
180
\li \c application.qml
181
\li \snippet qml/dynamicObjects-destroy.qml 0
182
183
\row
184
\li \c SelfDestroyingRect.qml
185
\li \snippet qml/SelfDestroyingRect.qml 0
186
187
\endtable
188
189
Alternatively, the \c application.qml could have destroyed the created object
190
by calling \c object.destroy().
191
192
Note that it is safe to call destroy() on an object within that object. Objects
193
are not destroyed the instant destroy() is called, but are cleaned up sometime
194
between the end of that script block and the next frame (unless you specified a
195
non-zero delay).
196
197
Note also that if a \c SelfDestroyingRect instance was created statically like
198
this:
199
200
\qml
201
Item {
202
SelfDestroyingRect {
203
// ...
204
}
205
}
206
\endqml
207
208
This would result in an error, since objects can only be dynamically
209
destroyed if they were dynamically created.
210
211
Objects created with \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}
212
can similarly be destroyed using \c destroy():
213
214
\snippet qml/createQmlObject.qml 0
215
\snippet qml/createQmlObject.qml destroy
216
217
*/
qtdeclarative
src
qml
doc
src
javascript
dynamicobjectcreation.qdoc
Generated on
for Qt by
1.14.0