summaryrefslogtreecommitdiffstats
path: root/doc/src/declarative/dynamicobjects.qdoc
blob: fede2cd6dbeb70da68972767a6f907d7717fa34c (plain)
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
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
\page qmldynamicobjects.html
\title Dynamic Object Creation

QML has some support for dynamically loading and managing QML objects from
within Javascript blocks. It is preferable to use the existing QML elements for
dynamic object management wherever possible; these are \l{Loader}, 
\l{Repeater}, \l{ListView}, \l{GridView} and \l{PathView}. It is also possible 
to dynamically create and manage objects from C++, and this is preferable for 
hybrid QML/C++ applications - see \l{Using QML in C++ Applications}.
Dynamically creating and managing objects from 
within Javascript blocks is intended for when none of the existing QML elements 
fit the needs of your application, and you do not desire for your application 
to involve C++ code.

\section1 Creating Objects Dynamically
There are two ways of creating objects dynamically. You can either create
a component which instantiates items, or create an item from a string of QML.
Creating a component is better for the situation where you have a predefined
item which you want to manage dynamic instances of, and creating an item from
a string of QML is intended for when the QML itself is generated at runtime.

If you have a component specified in a QML file, you can dynamically load it with
the 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.

You can also create a component by placing your QML inside a Component element.
Referencing that component element by id will be the same as referencing the variable
which you save the result of createComponent into.

Once you have a component you can use its createObject method to create an instance of
the component. Example QML script is below. Remember that QML files that might be loaded
    over the network cannot be expected to be ready immediately.
    \code
        var component;
        var sprite;
        function finishCreation(){
            if(component.isReady()){
                sprite = component.createObject();
                if(sprite == 0){
                    // Error Handling
                }else{
                    sprite.parent = page;
                    sprite.x = 200;
                    //...
                }
            }else if(component.isError()){
                // Error Handling
            }
        }

        component = createComponent("Sprite.qml");
        if(component.isReady()){
            finishCreation();
        }else{
            component.statusChanged.connect(finishCreation);
        }
    \endcode

    If you are certain the files will be local, you could simplify to

    \code
        component = createComponent("Sprite.qml");
        sprite = component.createObject();
        if(sprite == 0){
            // Error Handling
            console.log(component.errorsString());
        }else{
            sprite.parent = page;
            sprite.x = 200;
            //...
        }
    \endcode

After creating the item, remember to 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 createComponent is executed.

If the QML does not exist until runtime, you can create a QML item from
a string of QML using the createQmlObject function, as in the following example:

    \code
    newObject = createQmlObject('import Qt 4.6; Rectangle {color: "red"; width: 20; height: 20}',
        targetItem, "dynamicSnippet1");
    \endcode
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

Dynamically created objects may be used the same as other objects, however they
will not have an id in QML.

A restriction which you need to manage with dynamically created items,
is that the creation context must outlive the
created item. The creation context is the QmlContext in which createComponent
was called, or the context in which the Component element, or the item used as the
second argument to createQmlObject, was specified. If the creation
context is destroyed before the dynamic item is, then bindings in the dynamic item will
fail to work.

\section1 Deleting Objects Dynamically
You should generally avoid dynamically deleting objects that you did not
dynamically create. In many UIs, it is sufficient to set the opacity to 0 or
to move the item off of the edge of the screen. If you have lots of dynamically
created items however, deleting them when they are no longer used will provide
a worthwhile performance benefit. Note that you should never manually delete
items which were dynamically created by QML Elements such as \l{Loader}.

To manually delete a QML item, call its destroy method. This method has one
argument, which is an approximate delay in ms and which defaults to zero. This
allows you to wait until the completion of an animation or transition. An example:

\code
    Component{ id:fadesOut
        Rectangle{
            id: rect
            width: 40; height: 40;
            opacity: NumberAnimation{from:1; to:0; duration: 1000;}
            Component.onCompleted: rect.destroy(1000);
        }
    }
    function createFadesOut(parentItem)
    {
        var object = fadesOut.createObject();
        object.parent = parentItem;
    }
\endcode
In the above example, the dynamically created rectangle calls destroy as soon as it's created,
 but delays long enough for its fade out animation to play.

*/