aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/doc/src/bindings/qmltypes.qdoc
blob: c5f4ee8f8bb15db40f509411743c24dd74f4c849 (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
/****************************************************************************
**
** 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$
**
****************************************************************************/
/*!
\page qml-c++types.html
\title C++ Types as QML Types
\brief exposing Qt C++ types into the QML engine

The \l{The QML Engine}{QML engine} can instantiate any Qt C++ construct
such as \l{The Property System}{properties}, functions, and data models into
the QML context allowing the constructs to be accessible from within QML.

\target register-c++-type
\section1 Register a Type

    In an application or a \l{QML Plugins}{plugin}, the \c qmlRegisterType
    template will register a class to the QML engine.

\code
template<typename T>
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
\endcode

    \l qmlRegisterType() registers the C++ type \a T with the QML system, and
    makes it available to the QML context under the name \c qmlName in library
    \c uri version \c versionMajor.versionMinor. The \c qmlName can be the same
    as the C++ type name.

    Suppose that a \c Person class defined in a C++ is to be exposed into the
    QML context. The class must be a subclass of \l{QObject} and have a default
    constructor. The \l{The Property System}{properties} created with the
    Q_PROPERTY macro are visible in the QML context as well.
    \snippet examples/qml/cppextensions/referenceexamples/adding/person.h 0

    The application registers the class to the runtime with the
    \l{qmlRegisterType()}.

    \snippet examples/qml/cppextensions/referenceexamples/adding/main.cpp 0

    The Person type is then imported with the \c "People 1.0" module and its
    properties are accessible in a QML file.
    \snippet examples/qml/cppextensions/referenceexamples/adding/example.qml 0

    The \l {Extending QML - Adding Types Example}{Adding Types} example
    demonstrates as usage of the \l qmlRegisterType().

    Alternatively, these functions provide a way for other types of C++ types
    to be visible in the QML context.
    \list
    \li \l qmlRegisterModuleApi() is suited for registering either a QJSValue
    or QObject module API (shared instance) into a namespace
    \li \l qmlRegisterUncreatableType() is suited for attached
    properties and enum types.
    \li \l qmlRegisterTypeNotAvailable() is for
    reserving a namespace and suited for generating useful errors.
    \li \l qmlRegisterInterface() - for registering base or abstract classes for
    \l{qml-c++-coercion}{coercion and inheritance}. This is useful for general
    Qt objects or \l{Qt Objects and Interfaces}{pointers} to objects.
    \li \l qmlRegisterExtendedType() - for \l{qml-c++-extension}{extended types}
    \endlist

    \section2 Qt Objects and Interfaces
    QML can bind to complex objects such as pointers to objects or lists. As QML
    is typesafe, the \l{The QML Engine}{QML engine} ensures that only
    valid types are assigned to these properties.

    The QML engine treats pointers to objects or Qt interfaces the same
    way as regular properties. Thus, the lists or pointers are created as
    properties using the Q_PROPERTY() macro.

    \snippet examples/qml/cppextensions/referenceexamples/properties/birthdayparty.h 1

    The \c host is an \l{qml-expose-properties}{exposed property} that can bind
    to objects or lists of objects. The property type, in this case \c Person,
    must be \l{register-c++-type}{registered} into the runtime.

    QML also supports assigning Qt interfaces. To assign to a property whose
    type is a Qt interface pointer, the interface must also be registered with
    QML. As they cannot be instantiated directly, registering a Qt interface is
    different from registering a new QML type. The following function is used
    instead:

    \code
    template<typename T>
    int qmlRegisterInterface(const char *typeName)
    \endcode

    This function registers the C++ interface \a T with the QML system as \a
    typeName.

    Following registration, QML can \l{qml-c++-coercion}{coerce} objects that
    implement this interface for assignment to appropriately typed properties.

\section1 Type Revisions and Versions

    Type revisions and versions allow new properties or methods to exist in the
    new version while remaining compatible with previous versions.

    Consider these two QML files:
    \code
    // main.qml
    import QtQuick 1.0
    Item {
        id: root
        MyComponent {}
    }
    \endcode

    \code
    // MyComponent.qml
    import MyModule 1.0
    CppItem {
        value: root.x
    }
    \endcode
    where \c CppItem maps to the C++ class \c QCppItem.

    If the author of QCppItem adds a \c root property to QCppItem in a new
    version of the module, \c root.x now resolves to a different value because
    \c root is also the \c id of the top level component. The author could
    specify that the new \c root property is available from a specific minor
    version. This permits new properties and features to be added to existing
    elements without breaking existing programs.

    The REVISION tag is used to mark the \c root property as added in revision 1
    of the class. Methods such as Q_INVOKABLE's, signals and slots can also be
    tagged for a revision using the \c Q_REVISION(x) macro:

    \code
    class CppElement : public BaseObject
    {
        Q_OBJECT
        Q_PROPERTY(int root READ root WRITE setRoot NOTIFY rootChanged REVISION 1)

    signals:
        Q_REVISION(1) void rootChanged();
    };
    \endcode

    To register the new class revision to a particular version the following function is used:

    \code
    template<typename T, int metaObjectRevision>
    int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
    \endcode

    To register \c CppElement version 1 for \c {MyModule 1.1}:

    \code
    qmlRegisterType<QCppElement,1>("MyModule", 1, 1, "CppElement")
    \endcode

    \c root is only available when MyModule 1.1 is imported.

    For the same reason, new elements introduced in later versions should use
    the minor version argument of qmlRegisterType.

    This feature of the language allows for behavioural changes to be made
    without breaking existing applications. Consequently QML module authors
    should always remember to document what changed between minor versions, and
    QML module users should check that their application still runs correctly
    before deploying an updated import statement.

    You may also register the revision of a base class that your module depends upon
    using the qmlRegisterRevision() function:

    \code
    template<typename T, int metaObjectRevision>
    int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
    \endcode

    For example, if \c BaseObject is changed and now has a revision 1, you can specify that
    your module uses the new revision:

    \code
    qmlRegisterRevision<BaseObject,1>("MyModule", 1, 1);
    \endcode

    This is useful when deriving from base classes not declared as part of your
    module, e.g. when extending classes from the QtQuick library.

    The revision feature of QML allows for behavioral changes without breaking
    existing applications. Consequently, QML module authors should always
    remember to document what changed between minor versions, and QML module
    users should check that their application still runs correctly before
    deploying an updated import statement.

\target qml-c++-coercion
\section1 Inheritance and Coercion

    QML supports C++ inheritance hierarchies and can freely coerce between
    known, valid object types. This enables the creation of common base classes
    that allow the assignment of specialized classes to object or list
    properties.

    \snippet examples/qml/cppextensions/referenceexamples/coercion/example.qml 0

    The QML snippet shown above assigns a \c Boy object to the \c
    BirthdayParty's \c host property, and assigns three other objects to the \c
    guests property. Both the \c host and the \c guests properties binds to the
    \c Person type, but the assignment is valid as both the \c Boy and \c Girl
    objects inherit from \c Person.

    To assign to a property, the property's type must have been
    \l{register-c++-type}{registered} to the \l{The QML Engine}{declarative
    runtime}. If a type that acts purely as a base class that cannot be
    instantiated from QML needs to be registered as well. The
    \l qmlRegisterType() is useful for this occasion.

    \code
        template<typename T>
        int qmlRegisterType()
    \endcode

    This function registers the C++ type \a T with the QML system. The
    parameterless call to the template function qmlRegisterType() does not
    define a mapping between the C++ class and a QML element name, so the type
    is not instantiable from QML, but it is available for type coercion.

    \snippet examples/qml/cppextensions/referenceexamples/coercion/main.cpp 0
    \snippet examples/qml/cppextensions/referenceexamples/coercion/main.cpp register boy girl
    The \c Person class is registered withouth the parameters. Both the
    \c Boy and \c Girl class derive from the \c Person class.

    Type \a T must inherit QObject, but there are no restrictions on whether it
    is concrete or the signature of its constructor.

    QML will automatically coerce C++ types when assigning to either an object
    property, or to a list property. Only if coercion fails does an assignment
    error occur.

    The \l{Extending QML - Inheritance and Coercion Example}{Inheritance and Coercion Example}
    shows the complete code used to create the \c Boy and \c Girl types.

\target qml-c++-extension
\section1 Extension Objects

    \snippet examples/qml/cppextensions/referenceexamples/extended/example.qml 0

    The \c leftMargin property is a new property to an existing C++ type,
    \l QLineEdit, without modifying its source code.

    When integrating existing classes and technology into QML, APIs will
    often need tweaking to fit better into the declarative environment.
    Although the best results are usually obtained by modifying the original
    classes directly, if this is either not possible or is complicated by some
    other concerns, extension objects allow limited extension possibilities
    without direct modifications.

    \e{Extension objects} add additional properties to an existing type.
    Extension objects can only add properties, not signals or methods. An
    extended type definition allows the programmer to supply an additional type,
    known as the \e{extension type}, when registering the class. The
    properties are transparently merged with the original target class when used
    from within QML.

    The \l qmlRegisterExtendedType() is for registering extended types. Note
    that it has two forms.
    \code
    template<typename T, typename ExtendedT>
    int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)

    template<typename T, typename ExtendedT>
    int qmlRegisterExtendedType()
    \endcode
    functions should be used instead of the regular \c qmlRegisterType() variations.
    The arguments are identical to the corresponding non-extension registration functions,
    except for the ExtendedT parameter which is the type
    of the extension object.

    An extension class is a regular QObject, with a constructor that takes a
    QObject pointer. However, the extension class creation is delayed until the
    first extended property is accessed. The extension class is created and the
    target object is passed in as the parent. When the property on the original
    is accessed, the corresponding property on the extension object is used
    instead.

    The \l{Extending QML - Extension Objects}{Extension Objects} example
    demonstrates a usage of extension objects.

\section1 Property Value Sources

\snippet examples/qml/cppextensions/referenceexamples/valuesource/example.qml 0
\snippet examples/qml/cppextensions/referenceexamples/valuesource/example.qml 1

The QML snippet shown above applies a property value source to the \c announcement property.
A property value source generates a value for a property that changes over time.

Property value sources are most commonly used to do animation.  Rather than
constructing an animation object and manually setting the animation's "target"
property, a property value source can be assigned directly to a property of any
type and automatically set up this association.

The example shown here is rather contrived: the \c announcement property of the
\c BirthdayParty object is a string that is printed every time it is assigned and
the \c HappyBirthdaySong value source generates the lyrics of the song
"Happy Birthday".

\snippet examples/qml/cppextensions/referenceexamples/valuesource/birthdayparty.h 0

Normally, assigning an object to a string property would not be allowed.  In
the case of a property value source, rather than assigning the object instance
itself, the QML engine sets up an association between the value source and
the property.

Property value sources are special types that derive from the
QQmlPropertyValueSource base class.  This base class contains a single method,
QQmlPropertyValueSource::setTarget(), that the QML engine invokes when
associating the property value source with a property.  The relevant part of
the \c HappyBirthdaySong type declaration looks like this:

\snippet examples/qml/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 0
\snippet examples/qml/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 1
\snippet examples/qml/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 2

In all other respects, property value sources are regular QML types.  They must
be registered with the QML engine using the same macros as other types, and can
contain properties, signals and methods just like other types.

When a property value source object is assigned to a property, QML first tries
to assign it normally, as though it were a regular QML type.  Only if this
assignment fails does the engine call the \l {QQmlPropertyValueSource::}{setTarget()} method.  This allows
the type to also be used in contexts other than just as a value source.

\l {Extending QML -  Property Value Source Example} shows the complete code used
to implement the \c HappyBirthdaySong property value source.

\section1 Optimization and Other Considerations

The \l{qml-engine-optimization}{ QML Engine} article suggests possible
optimization considerations as memory management and QVariant type usages.

*/