aboutsummaryrefslogtreecommitdiffstats
path: root/doc/src/qml/qmlengine.qdoc
blob: 3e8ef1ae3f16acf557c5658d763595b77279b9cd (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
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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
\target qmlengine
\page qmlengine.html
\ingroup qml-features
\title The QML Engine
\brief the engine runs QML applications

The QML engine runs and executes QML
applications. The engine loads, instantiates, and executes the QML context as
specified in QML files, plugins, or applications.

\section1 Core Module Classes

    The \l{QtDeclarative}{Qt Declarative} module provides a set of C++ APIs for
    extending your QML applications from C++ and embedding QML into C++
    applications. There are several core classes in the Qt Declarative module
    that provide the essential capabilities for doing this. These are:

    \list
    \o QDeclarativeEngine: A QML engine provides the environment for executing QML code. Every
    application requires at least one engine instance.
    \o QDeclarativeComponent: A component encapsulates QML information.
    \o QDeclarativeContext: A context allows an application to expose data to
    the QML components created by an engine.
    \endlist

    The Qt Declarative module consists of the engine,
    context, component encapsulation, and visual items.

    \list
    \o QQuickItem
    \o QQuickPaintedItem
    \o QQuickView
    \endlist

    \section2 Declarative Engine
        A QDeclarativeEngine allows the configuration of global settings that
        apply to all of its QML component instances: for example, the
        QNetworkAccessManager to be used for network communications, and the
        file path to be used for persistent storage.

        QDeclarativeComponent is used to load QML documents. Each
        QDeclarativeComponent instance represents a single document. A component
        can be created from the URL or file path of a QML document, or the raw
        QML code of the document. Component instances are instatiated through
        the QDeclarativeComponent::create() method, like this:

        \code
        QDeclarativeEngine engine;
        QDeclarativeComponent component(&engine, QUrl::fromLocalFile("MyRectangle.qml"));
        QObject *rectangleInstance = component.create();

        // ...
        delete rectangleInstance;
        \endcode

        QML documents can also be loaded using QDeclarativeView. This class
        provides a convenient QWidget-based view for embedding QML components
        into QGraphicsView-based applications. (For other methods of integrating
        QML into QWidget-based applications, see \l {Integrating QML Code with
        existing Qt UI code}.)

\section1 Engine and Context Initialization

    \section2 Loading QML Components from C++

    A QML document can be loaded with QDeclarativeComponent or QDeclarativeView.
    QDeclarativeComponent loads a QML component as a C++ object;
    QDeclarativeView also does this, but additionally loads the QML component
    directly into a QGraphicsView. It is convenient for loading a displayable
    QML component into a QWidget-based application.

    For example, suppose there is a \c MyItem.qml file that looks like this:

    \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml start
    \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml end

    This QML document can be loaded with QDeclarativeComponent or
    QDeclarativeView with the following C++ code. Using a QDeclarativeComponent
    requires calling QDeclarativeComponent::create() to create a new instance of
    the component, while a QDeclarativeView automatically creates an instance of
    the component, which is accessible via QDeclarativeView::rootObject():

    \table
    \row
    \o
    \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp QDeclarativeComponent-a
    \dots 0
    \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp QDeclarativeComponent-b
    \o
    \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp QDeclarativeView
    \endtable

    This \c object is the instance of the \c MyItem.qml component that has been
    created. You can now modify the item's properties using
    QObject::setProperty() or QDeclarativeProperty:

    \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp properties

    Alternatively, you can cast the object to its actual type and call functions
    with compile-time safety. In this case the base object of \c MyItem.qml is
    an \l Item, which is defined by the QDeclarativeItem class:

    \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp cast

    You can also connect to any signals or call functions defined in the
    component using QMetaObject::invokeMethod() and QObject::connect(). See \l
    {Exchanging data between QML and C++} below for further details.

    \section3 Locating child objects

    QML components are essentially object trees with children that have siblings
    and their own children. Child objects of QML components can be located using
    the QObject::objectName property with QObject::findChild(). For example, if
    the root item in \c MyItem.qml had a child \l Rectangle item:

    \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml start
    \codeline
    \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml child
    \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml end

    The child could be located like this:

    \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp findChild

    If \c objectName is used inside a delegate of a ListView, \l Repeater or
    some other element that creates multiple instances of its delegates, there
    will be multiple children with the same \c objectName. In this case,
    QObject::findChildren() can be used to find all children with a matching \c
    objectName.

    \warning While it is possible to use C++ to access and manipulate QML
    objects deep into the object tree, we recommend that you do not take this
    approach outside of application testing and prototyping. One strength of QML
    and C++ integration is the ability to implement the QML user interface
    separately from the C++ logic and dataset backend, and this strategy breaks
    if the C++ side reaches deep into the QML components to manipulate them
    directly. This would make it difficult to, for example, swap a QML view
    component for another view, if the new component was missing a required \c
    objectName. It is better for the C++ implementation to know as little as
    possible about the QML user interface implementation and the composition of
    the QML object tree.


    \section2 Embedding C++ Objects into QML Components

    When loading a QML scene into a C++ application, it can be useful to
    directly embed C++ data into the QML object. QDeclarativeContext enables
    this by exposing data to the context of a QML component, allowing data to be
    injected from C++ into QML.

    For example, here is a QML item that refers to a \c currentDateTime value
    that does not exist in the current scope:

    \snippet doc/src/snippets/declarative/qtbinding/context/MyItem.qml 0

    This \c currentDateTime value can be set directly by the C++ application
    that loads the QML component, using
    QDeclarativeContext::setContextProperty():

    \snippet doc/src/snippets/declarative/qtbinding/context/main.cpp 0

    Context properties can hold either QVariant or QObject* values. This means
    custom C++ objects can also be injected using this approach, and these
    objects can be modified and read directly in QML. Here, we modify the above
    example to embed a QObject instance instead of a QDateTime value, and the
    QML code invokes a method on the object instance:

    \table
    \row
    \o
    \snippet doc/src/snippets/declarative/qtbinding/context-advanced/applicationdata.h 0
    \codeline
    \snippet doc/src/snippets/declarative/qtbinding/context-advanced/main.cpp 0
    \o
    \snippet doc/src/snippets/declarative/qtbinding/context-advanced/MyItem.qml 0
    \endtable

    (Note that date/time values returned from C++ to QML can be formatted through
    \l{QML:Qt::formatDateTime}{Qt.formatDateTime()} and associated functions.)

    If the QML item needs to receive signals from the context property, it can
    connect to them using the \l Connections element. For example, if \c
    ApplicationData has a signal named \c dataChanged(), this signal can be
    connected to using an \c onDataChanged handler within a \l Connections
    object:

    \snippet doc/src/snippets/declarative/qtbinding/context-advanced/connections.qml 0

    Context properties can be useful for using C++ based data models in a QML view. See the
    \l {declarative/modelviews/stringlistmodel}{String ListModel},
    \l {declarative/modelviews/objectlistmodel}{Object ListModel} and
    \l {declarative/modelviews/abstractitemmodel}{AbstractItemModel} models for
    respective examples on using QStringListModel, QObjectList-based models and QAbstractItemModel
    in QML views.

    Also see the QDeclarativeContext documentation for more information.


\section1 Invoking QML Entities through the Engine

    QML and C++ objects can communicate with one another through signals, slots
    and property modifications. For a C++ object, any data that is exposed to
    Qt's \l{The Meta-Object System}{Meta-Object System} that is, properties,
    signals, slots and Q_INVOKABLE methods - become available to QML. On the QML
    side, all QML object data is automatically made available to the meta-object
    system and can be accessed from C++.

    The \l{Creating QML Types} article covers the topic of exposing Qt functions
    and properties to the declarative engine.

    \section2 Calling Functions

    QML functions can be called from C++ and vice-versa.

    All QML functions are exposed to the meta-object system and can be called
    using QMetaObject::invokeMethod(). Here is a C++ application that uses this
    to call a QML function:

    \table
    \row
    \o \snippet doc/src/snippets/declarative/qtbinding/functions-qml/MyItem.qml 0
    \o \snippet doc/src/snippets/declarative/qtbinding/functions-qml/main.cpp 0
    \endtable

    Notice the Q_RETURN_ARG() and Q_ARG() arguments for
    QMetaObject::invokeMethod() must be specified as QVariant types, as this is
    the generic data type used for QML functions and return values.

    To call a C++ function from QML, the function must be either a Qt slot, or a
    function marked with the Q_INVOKABLE macro, to be available to QML. In the
    following example, the QML code invokes methods on the \c myObject object,
    which has been set using QDeclarativeContext::setContextProperty():

    \table
    \row
    \o
    \snippet doc/src/snippets/declarative/qtbinding/functions-cpp/MyItem.qml 0
    \o
    \snippet doc/src/snippets/declarative/qtbinding/functions-cpp/myclass.h 0
    \codeline
    \snippet doc/src/snippets/declarative/qtbinding/functions-cpp/main.cpp 0
    \endtable

    QML supports the calling of overloaded C++ functions. If there are multiple
    C++ functions with the same name but different arguments, the correct
    function will be called according to the number and the types of arguments
    that are provided.


    \section2 Receiving Signals

    All QML signals are automatically available to C++, and can be connected to
    using QObject::connect() like any ordinary Qt C++ signal. In return, any C++
    signal can be received by a QML object using \l {Signal Handlers}{signal
    handlers}.

    Here is a QML component with a signal named \c qmlSignal. This signal is
    connected to a C++ object's slot using QObject::connect(), so that the \c
    cppSlot() method is called whenever the \c qmlSignal is emitted:

    \table
    \row
    \o
    \snippet doc/src/snippets/declarative/qtbinding/signals-qml/MyItem.qml 0
    \o
    \snippet doc/src/snippets/declarative/qtbinding/signals-qml/myclass.h 0
    \codeline
    \snippet doc/src/snippets/declarative/qtbinding/signals-qml/main.cpp 0
    \endtable

    To connect to Qt C++ signals from within QML, use a signal handler with the
    \c on<SignalName> syntax. If the C++ object is directly creatable from
    within QML (see \l {Defining new QML elements} above) then the signal
    handler can be defined within the object declaration. In the following
    example, the QML code creates a \c ImageViewer object, and the \c
    imageChanged and \c loadingError signals of the C++ object are connected to
    through \c onImagedChanged and \c onLoadingError signal handlers in QML:

    \table
    \row
    \o

    \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/imageviewer.h start
    \dots 4
    \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/imageviewer.h end

    \o
    \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/standalone.qml 0
    \endtable

    (Note that if a signal has been declared as the NOTIFY signal for a
    property, QML allows it to be received with an \c on<Property>Changed
    handler even if the signal's name does not follow the \c <Property>Changed
    naming convention. In the above example, if the "imageChanged" signal was
    named "imageModified" instead, the \c onImageChanged signal handler would
    still be called.)

    If, however, the object with the signal is not created from within the QML
    code, and the QML item only has a reference to the created object - for
    example, if the object was set using
    QDeclarativeContext::setContextProperty() - then the \l Connections element
    can be used instead to create the signal handler:

    \table
    \row
    \o \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/main.cpp connections
    \o \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/MyItem.qml 0
    \endtable

    C++ signals can use enum values as parameters provided that the enum is
    declared in the class that is emitting the signal, and that the enum is
    registered using Q_ENUMS. See \l {Using enumerations of a custom type} below
    for details.


    \section2 Modifying Properties

    Any properties declared in a QML object are automatically accessible from
    C++. Given a QML item like this:

    \snippet doc/src/snippets/declarative/qtbinding/properties-qml/MyItem.qml 0

    The value of the \c someNumber property can be set and read using
    QDeclarativeProperty, or QObject::setProperty() and QObject::property():

    \snippet doc/src/snippets/declarative/qtbinding/properties-qml/main.cpp 0

    You should always use QObject::setProperty(), QDeclarativeProperty or
    QMetaProperty::write() to change a QML property value, to ensure the QML
    engine is made aware of the property change. For example, say you have a
    custom element \c PushButton with a \c buttonText property that internally
    reflects the value of a \c m_buttonText member variable. Modifying the
    member variable directly like this is not a good idea:

    \badcode
    // BAD!
    QDeclarativeComponent component(engine, "MyButton.qml");
    PushButton *button = qobject_cast<PushButton*>(component.create());
    button->m_buttonText = "Click me";
    \endcode
    Since the value is changed directly, this bypasses Qt's \l{The Meta-Object
    System}{meta-object system} and the QML engine is not made aware of the
    property change. This means property bindings to \c buttonText would not be
    updated, and any \c onButtonTextChanged handlers would not be called.

    \target properties-cpp

    Any \l {The Property System}{Qt properties} - that is, those declared with
    the Q_PROPERTY() macro - are accessible from QML. Here is a modified version
    of the \l {Embedding C++ objects into QML components}{earlier example} on
    this page; here, the \c ApplicationData class has a \c backgroundColor
    property. This property can be written to and read from QML:

    \table
    \row
    \o \snippet doc/src/snippets/declarative/qtbinding/properties-cpp/applicationdata.h 0
    \o \snippet doc/src/snippets/declarative/qtbinding/properties-cpp/MyItem.qml 0
    \endtable

    Notice the \c backgroundColorChanged signal is declared as the NOTIFY signal
    for the \c backgroundColor property. If a Qt property does not have an
    associated NOTIFY signal, the property cannot be used for \l{Property
    Binding in QML}, as the QML engine would not be notified when the value
    changes. If you are using custom types in QML, make sure their properties
    have NOTIFY signals so that they can be used in property bindings.

    The \l{Creating QML Types} article covers the topic of exposing Qt
    properties to the runtime. For more information, the
    \l{Tutorial: Writing QML extensions with C++}{Writing QML extensions with C++}
    tutorial demonstrates basic usage patterns.

\section1 Loading QML Plugins

    Additional Qt code is runnable in the engine as a QML plugin. The \l{QML
    Plugins} article covers the creation and usage patterns of QML plugins. The
    QDeclarativeExtensionPlugin class is an abstract class for writing QML
    plugins. The \l {How to Create Qt Plugins} contains more information about
    Qt's plugin system.

\target qml-engine-optimization
\section1 Optimization

    Often, to develop high performance elements it is helpful to know more about
    the status of the QML engine. For example, it might be beneficial to delay
    initializing some costly data structures until after all the properties have
    been set.

    The QML engine defines an interface class called QDeclarativeParserStatus,
    which contains a number of virtual methods that are invoked at various
    stages during component instantiation. To receive these notifications, an
    element implementation inherits QDeclarativeParserStatus and notifies the Qt
    meta system using the Q_INTERFACES() macro.

    \code
    class Example : public QObject, public QDeclarativeParserStatus
    {
        Q_OBJECT
        Q_INTERFACES(QDeclarativeParserStatus)
    public:
        virtual void componentComplete()
        {
            qDebug() << "Woohoo!  Now to do my costly initialization";
        }
    };
    \endcode

\section1 Memory Management and QVariant types

    It is a component's responsibility to ensure that it does not access or
    return pointers to invalid objects. QML makes the following guarentees:

    \list
    \o An object assigned to a QObject (or QObject-derived) pointer property
    will be valid at the time of assignment.

    Following assignment, it is the responsibility of the class to subsequently
    guard this pointer, either through a class specific method or the generic
    QPointer class.

    \o An object assigned to a QVariant will be valid at the time of assignment.

    When assigning an object to a QVariant property, QML will always use a
    QMetaType::QObjectStar typed QVariant. It is the responsibility of the class
    to guard the pointer. A general rule when writing a class that uses QVariant
    properties is to check the type of the QVariant when it is set and if the
    type is not handled by your class, reset it to an invalid variant.

    \o An object assigned to a QObject (or QObject-derived) list property will
    be valid at the time of assignment.

    Following assignment, it is the responsibility of the class to subsequently
    guard this pointer, either through a class specific method or the generic
    QPointer class.
    \endlist

    Components should assume that any QML assigned object can be deleted at any
    time, and respond accordingly. If documented as such an element need not
    continue to work in this situation, but it must not crash.

\section1 JavaScript Runtime

    The runtime implements the \l{ECMA-262}{ECMAScript Language Specification} standard.
    The reserved words, conditionals, variables, and object behaviors follow
    after the standard.

    The \l{JavaScript Code} article has information about placing JavaScript
    code within QML code.

*/