/usr/share/qt5/doc/qtqml/qtqml-javascript-dynamicobjectcreation.html is in qtdeclarative5-doc-html 5.9.5-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- dynamicobjectcreation.qdoc -->
<title>Dynamic QML Object Creation from JavaScript | Qt QML 5.9</title>
<link rel="stylesheet" type="text/css" href="style/offline-simple.css" />
<script type="text/javascript">
document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css");
// loading style sheet breaks anchors that were jumped to before
// so force jumping to anchor again
setTimeout(function() {
var anchor = location.hash;
// need to jump to different anchor first (e.g. none)
location.hash = "#";
setTimeout(function() {
location.hash = anchor;
}, 0);
}, 0);
</script>
</head>
<body>
<div class="header" id="qtdocheader">
<div class="main">
<div class="main-rounded">
<div class="navigationbar">
<table><tr>
<td >Qt 5.9</td><td ><a href="qtqml-index.html">Qt QML</a></td><td >Dynamic QML Object Creation from JavaScript</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right">Qt 5.9.5 Reference Documentation</td>
</tr></table>
</div>
</div>
<div class="content">
<div class="line">
<div class="content mainContent">
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#creating-objects-dynamically">Creating Objects Dynamically</a></li>
<li class="level2"><a href="#creating-a-component-dynamically">Creating a Component Dynamically</a></li>
<li class="level2"><a href="#creating-an-object-from-a-string-of-qml">Creating an Object from a String of QML</a></li>
<li class="level1"><a href="#maintaining-dynamically-created-objects">Maintaining Dynamically Created Objects</a></li>
<li class="level1"><a href="#deleting-objects-dynamically">Deleting Objects Dynamically</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Dynamic QML Object Creation from JavaScript</h1>
<span class="subtitle"></span>
<!-- $$$qtqml-javascript-dynamicobjectcreation.html-description -->
<div class="descr"> <a name="details"></a>
<p>QML supports the dynamic creation of objects from within JavaScript. This is useful to delay instantiation of objects until necessary, thereby improving application startup time. It also allows visual objects to be dynamically created and added to the scene in reaction to user input or other events.</p>
<p>See the <a href="qtqml-dynamicscene-example.html">Dynamic Scene example</a> for a demonstration of the concepts discussed on this page.</p>
<a name="creating-objects-dynamically"></a>
<h2 id="creating-objects-dynamically">Creating Objects Dynamically</h2>
<p>There are two ways to create objects dynamically from JavaScript. You can either call <a href="qml-qtqml-qt.html#createComponent-method">Qt.createComponent()</a> to dynamically create a <a href="qml-qtqml-component.html">Component</a> object, or use <a href="qml-qtqml-qt.html#createQmlObject-method">Qt.createQmlObject()</a> to create an object from a string of QML. Creating a component is better if you have an existing component defined in a QML document and you want to dynamically create instances of that component. Otherwise, creating an object from a string of QML is useful when the object QML itself is generated at runtime.</p>
<a name="creating-a-component-dynamically"></a>
<h3 >Creating a Component Dynamically</h3>
<p>To dynamically load a component defined in a QML file, call the <a href="qml-qtqml-qt.html#createComponent-method">Qt.createComponent()</a> function in the <a href="qml-qtqml-qt.html">Qt object</a>. This function takes the URL of the QML file as its only argument and creates a <a href="qml-qtqml-component.html">Component</a> object from this URL.</p>
<p>Once you have a <a href="qml-qtqml-component.html">Component</a>, you can call its <a href="qml-qtqml-component.html#createObject-method">createObject()</a> method to create an instance of the component. This function can take one or two arguments:</p>
<ul>
<li>The first is the parent for the new object. The parent can be a graphical object (i.e. of the Item type) or non-graphical object (i.e. of the <a href="qml-qtqml-qtobject.html">QtObject</a> or C++ <a href="../qtcore/qobject.html">QObject</a> type). Only graphical objects with graphical parent objects will be rendered to the Qt Quick visual canvas. If you wish to set the parent later you can safely pass <code>null</code> to this function.</li>
<li>The second is optional and is a map of property-value pairs that define initial any property values for the object. Property values specified by this argument are applied to the object before its creation is finalized, avoiding binding errors that may occur if particular properties must be initialized to enable other property bindings. Additionally, there are small performance benefits when compared to defining property values and bindings after the object is created.</li>
</ul>
<p>Here is an example. First there is <code>Sprite.qml</code>, which defines a simple QML component:</p>
<pre class="qml">
import QtQuick 2.0
<span class="type">Rectangle</span> { <span class="name">width</span>: <span class="number">80</span>; <span class="name">height</span>: <span class="number">50</span>; <span class="name">color</span>: <span class="string">"red"</span> }
</pre>
<p>Our main application file, <code>main.qml</code>, imports a <code>componentCreation.js</code> JavaScript file that will create <code>Sprite</code> objects:</p>
<pre class="qml">
import QtQuick 2.0
import "componentCreation.js" as MyScript
<span class="type">Rectangle</span> {
<span class="name">id</span>: <span class="name">appWindow</span>
<span class="name">width</span>: <span class="number">300</span>; <span class="name">height</span>: <span class="number">300</span>
<span class="name">Component</span>.onCompleted: <span class="name">MyScript</span>.<span class="name">createSpriteObjects</span>();
}
</pre>
<p>Here is <code>componentCreation.js</code>. Notice it checks whether the component <a href="qml-qtqml-component.html#status-prop">status</a> is <code>Component.Ready</code> before calling <a href="qml-qtqml-component.html#createObject-method">createObject()</a> in case the QML file is loaded over a network and thus is not ready immediately.</p>
<pre class="js">
var <span class="name">component</span>;
var <span class="name">sprite</span>;
<span class="keyword">function</span> <span class="name">createSpriteObjects</span>() {
<span class="name">component</span> <span class="operator">=</span> <span class="name">Qt</span>.<span class="name">createComponent</span>(<span class="string">"Sprite.qml"</span>);
<span class="keyword">if</span> (<span class="name">component</span>.<span class="name">status</span> <span class="operator">==</span> <span class="name">Component</span>.<span class="name">Ready</span>)
<span class="name">finishCreation</span>();
<span class="keyword">else</span>
<span class="name">component</span>.<span class="name">statusChanged</span>.<span class="name">connect</span>(<span class="name">finishCreation</span>);
}
<span class="keyword">function</span> <span class="name">finishCreation</span>() {
<span class="keyword">if</span> (<span class="name">component</span>.<span class="name">status</span> <span class="operator">==</span> <span class="name">Component</span>.<span class="name">Ready</span>) {
<span class="name">sprite</span> <span class="operator">=</span> <span class="name">component</span>.<span class="name">createObject</span>(<span class="name">appWindow</span>, {"x": <span class="number">100</span>, "y": <span class="number">100</span>});
<span class="keyword">if</span> (<span class="name">sprite</span> <span class="operator">==</span> <span class="number">null</span>) {
<span class="comment">// Error Handling</span>
<span class="name">console</span>.<span class="name">log</span>(<span class="string">"Error creating object"</span>);
}
} <span class="keyword">else</span> <span class="keyword">if</span> (<span class="name">component</span>.<span class="name">status</span> <span class="operator">==</span> <span class="name">Component</span>.<span class="name">Error</span>) {
<span class="comment">// Error Handling</span>
<span class="name">console</span>.<span class="name">log</span>(<span class="string">"Error loading component:"</span>, <span class="name">component</span>.<span class="name">errorString</span>());
}
}
</pre>
<p>If you are certain the QML file to be loaded is a local file, you could omit the <code>finishCreation()</code> function and call <a href="qml-qtqml-component.html#createObject-method">createObject()</a> immediately:</p>
<pre class="js">
<span class="keyword">function</span> <span class="name">createSpriteObjects</span>() {
<span class="name">component</span> <span class="operator">=</span> <span class="name">Qt</span>.<span class="name">createComponent</span>(<span class="string">"Sprite.qml"</span>);
<span class="name">sprite</span> <span class="operator">=</span> <span class="name">component</span>.<span class="name">createObject</span>(<span class="name">appWindow</span>, {"x": <span class="number">100</span>, "y": <span class="number">100</span>});
<span class="keyword">if</span> (<span class="name">sprite</span> <span class="operator">==</span> <span class="number">null</span>) {
<span class="comment">// Error Handling</span>
<span class="name">console</span>.<span class="name">log</span>(<span class="string">"Error creating object"</span>);
}
}
</pre>
<p>Notice in both instances, <a href="qml-qtqml-component.html#createObject-method">createObject()</a> is called with <code>appWindow</code> passed as the parent argument, since the dynamically created object is a visual (Qt Quick) object. The created object will become a child of the <code>appWindow</code> object in <code>main.qml</code>, and appear in the scene.</p>
<p>When using files with relative paths, the path should be relative to the file where <a href="qml-qtqml-qt.html#createComponent-method">Qt.createComponent()</a> is executed.</p>
<p>To connect signals to (or receive signals from) dynamically created objects, use the signal <code>connect()</code> method. See <a href="qtqml-syntax-signals.html#connecting-signals-to-methods-and-signals">Connecting Signals to Methods and Signals</a> for more information.</p>
<p>It is also possible to instantiate components without blocking via the <a href="qml-qtqml-component.html#incubateObject-method">incubateObject()</a> function.</p>
<a name="creating-an-object-from-a-string-of-qml"></a>
<h3 >Creating an Object from a String of QML</h3>
<p>If the QML is not defined until runtime, you can create a QML object from a string of QML using the <a href="qml-qtqml-qt.html#createQmlObject-method">Qt.createQmlObject()</a> function, as in the following example:</p>
<pre class="qml">
var <span class="name">newObject</span> = <span class="name">Qt</span>.<span class="name">createQmlObject</span>(<span class="string">'import QtQuick 2.0; Rectangle {color: "red"; width: 20; height: 20}'</span>,
<span class="name">parentItem</span>,
<span class="string">"dynamicSnippet1"</span>);
</pre>
<p>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. The second argument is the parent object for the new object, and the parent argument semantics which apply to components are similarly applicable for <code>createQmlObject()</code>. The third argument is the file path to associate with the new object; this is used for error reporting.</p>
<p>If the string of QML imports files using relative paths, the path should be relative to the file in which the parent object (the second argument to the method) is defined.</p>
<p><b>Important: </b>When building static QML applications, QML files are scanned to detect import dependencies. That way, all necessary plugins and resources are resolved at compile time. However, only explicit import statements are considered (those found at the top of a QML file), and not import statements enclosed within string literals. To support static builds, you therefore need to ensure that QML files using <a href="qml-qtqml-qt.html#createQmlObject-method">Qt.createQmlObject()</a>, explicitly contain all necessary imports at the top of the file in addition to inside the string literals.</p><a name="maintaining-dynamically-created-objects"></a>
<h2 id="maintaining-dynamically-created-objects">Maintaining Dynamically Created Objects</h2>
<p>When managing dynamically created objects, you must ensure the creation context outlives the created object. Otherwise, if the creation context is destroyed first, the bindings in the dynamic object will no longer work.</p>
<p>The actual creation context depends on how an object is created:</p>
<ul>
<li>If <a href="qml-qtqml-qt.html#createComponent-method">Qt.createComponent()</a> is used, the creation context is the <a href="qqmlcontext.html">QQmlContext</a> in which this method is called</li>
<li>If <a href="qml-qtqml-qt.html#createQmlObject-method">Qt.createQmlObject()</a> is called, the creation context is the context of the parent object passed to this method</li>
<li>If a <code>Component{}</code> object is defined and <a href="qml-qtqml-component.html#createObject-method">createObject()</a> or <a href="qml-qtqml-component.html#incubateObject-method">incubateObject()</a> is called on that object, the creation context is the context in which the <code>Component</code> is defined</li>
</ul>
<p>Also, note that while dynamically created objects may be used the same as other objects, they do not have an id in QML.</p>
<a name="deleting-objects-dynamically"></a>
<h2 id="deleting-objects-dynamically">Deleting Objects Dynamically</h2>
<p>In many user interfaces, it is sufficient to set a visual object's opacity to 0 or to move the visual object off the screen instead of deleting it. If you have lots of dynamically created objects, however, you may receive a worthwhile performance benefit if unused objects are deleted.</p>
<p>Note that you should never manually delete objects that were dynamically created by convenience QML object factories (such as Loader and Repeater). Also, you should avoid deleting objects that you did not dynamically create yourself.</p>
<p>Items can be deleted using the <code>destroy()</code> 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.</p>
<p>Here is an example. The <code>application.qml</code> creates five instances of the <code>SelfDestroyingRect.qml</code> component. Each instance runs a NumberAnimation, and when the animation has finished, calls <code>destroy()</code> on its root object to destroy itself:</p>
<div class="table"><table class="generic">
<tr valign="top" class="odd"><td ><code>application.qml</code></td><td ><pre class="qml">
import QtQuick 2.0
<span class="type">Item</span> {
<span class="name">id</span>: <span class="name">container</span>
<span class="name">width</span>: <span class="number">500</span>; <span class="name">height</span>: <span class="number">100</span>
<span class="name">Component</span>.onCompleted: {
var <span class="name">component</span> = <span class="name">Qt</span>.<span class="name">createComponent</span>(<span class="string">"SelfDestroyingRect.qml"</span>);
<span class="keyword">for</span> (<span class="keyword">var</span> <span class="name">i</span>=<span class="number">0</span>; <span class="name">i</span><span class="operator"><</span><span class="number">5</span>; i++) {
var <span class="name">object</span> = <span class="name">component</span>.<span class="name">createObject</span>(<span class="name">container</span>);
<span class="name">object</span>.<span class="name">x</span> <span class="operator">=</span> (<span class="name">object</span>.<span class="name">width</span> <span class="operator">+</span> <span class="number">10</span>) <span class="operator">*</span> <span class="name">i</span>;
}
}
}
</pre>
</td></tr>
<tr valign="top" class="even"><td ><code>SelfDestroyingRect.qml</code></td><td ><pre class="qml">
import QtQuick 2.0
<span class="type">Rectangle</span> {
<span class="name">id</span>: <span class="name">rect</span>
<span class="name">width</span>: <span class="number">80</span>; <span class="name">height</span>: <span class="number">80</span>
<span class="name">color</span>: <span class="string">"red"</span>
NumberAnimation on <span class="name">opacity</span> {
<span class="name">to</span>: <span class="number">0</span>
<span class="name">duration</span>: <span class="number">1000</span>
<span class="name">onRunningChanged</span>: {
<span class="keyword">if</span> (!<span class="name">running</span>) {
<span class="name">console</span>.<span class="name">log</span>(<span class="string">"Destroying..."</span>)
<span class="name">rect</span>.<span class="name">destroy</span>();
}
}
}
}
</pre>
</td></tr>
</table></div>
<p>Alternatively, the <code>application.qml</code> could have destroyed the created object by calling <code>object.destroy()</code>.</p>
<p>Note that it is safe to call destroy() on an object within that object. Objects are not destroyed the instant destroy() is called, but are cleaned up sometime between the end of that script block and the next frame (unless you specified a non-zero delay).</p>
<p>Note also that if a <code>SelfDestroyingRect</code> instance was created statically like this:</p>
<pre class="qml">
<span class="type">Item</span> {
<span class="type">SelfDestroyingRect</span> {
<span class="comment">// ...</span>
}
}
</pre>
<p>This would result in an error, since objects can only be dynamically destroyed if they were dynamically created.</p>
<p>Objects created with <a href="qml-qtqml-qt.html#createQmlObject-method">Qt.createQmlObject()</a> can similarly be destroyed using <code>destroy()</code>:</p>
<pre class="qml">
var <span class="name">newObject</span> = <span class="name">Qt</span>.<span class="name">createQmlObject</span>(<span class="string">'import QtQuick 2.0; Rectangle {color: "red"; width: 20; height: 20}'</span>,
<span class="name">parentItem</span>,
<span class="string">"dynamicSnippet1"</span>);
<span class="name">newObject</span>.<span class="name">destroy</span>(<span class="number">1000</span>);
</pre>
</div>
<!-- @@@qtqml-javascript-dynamicobjectcreation.html -->
</div>
</div>
</div>
</div>
</div>
<div class="footer">
<p>
<acronym title="Copyright">©</acronym> 2017 The Qt Company Ltd.
Documentation contributions included herein are the copyrights of
their respective owners.<br> The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation.<br> Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property
of their respective owners. </p>
</div>
</body>
</html>
|