aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/doc/src/bindings/properties-methods-signals.qdoc
blob: 2aa11e9a505c39bd4d8d834b560c87cfe911fc8e (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
/****************************************************************************
**
** 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-properties-signals-methods.html
\title C++ Properties, Methods, and Signals in QML
\brief Exposing C++ properties, methods, and signals to QML
\target qml-expose-properties

\section1 Exposing Qt C++ Properties

    The \l{The QML Engine}{QML engine} utilizes Qt's
    \l{The Property System}{Property System} and in effect, QML
    \l{Property Binding in QML}{property bindings} also use Qt properties.

    Essentially, a Qt C++ property has a \e write function, \e read function,
    and has a signal function. QML properties are inheritely public, both
    readable and writable, albeit type-safe. QML properties may also have
    signals which are emitted when the property value or binding changes.

    The QML property equivalent of a Qt C++ property is created as a property
    with the \l Q_PROPERTY() macro. There needs to be C++ functions assigned as
    the property's read, write, and signal handler function.

    The \l {register-c++-type}{Register a Type} section mentions that the
    \c Person class has properties that are exposed to the QML context. The QML
    properties are created with the \c Q_PROPERTY macro. The macro associates
    the properties to the read, write, and singal functions in its argument.

\code
Q_PROPERTY(int size READ size WRITE setSize NOTIFY shoeChanged)
\endcode

    A \c Shoe class might have an integer property called \c size. We set the \c
    size() function as the \c READ function and the \c setSize() function to be
    the \c WRITE function. In a QML application, when a property is read, the \c
    size() is called and when the property's binding changes, the \c setSize()
    is called. The READ function, by definition, must return the same type as
    the property.

    We may also connect a \l{signals and slots}{signal} to a property. The \c
    size property may have a \c shoeChanged signal indicated after the \c NOTIFY
    parameter of the macro. The \c shoeChanged becomes a \l{QML Signal and
    Handler Event System}{QML signal} and the runtime will create QML handler
    called \c onShoeChanged. Whenever the size property's binding changes, the
    \c shoeChanged signal is emitted and the \c onShoeChanged handler is
    invoked. In the handler, commands such as \l{JavaScript Expressions in
    QML}{JavaScript expressions} can perform clean-up operations or call other
    functions.

    \b{Note:} The QML signal handler will always be named
    on<Property-name>Changed, regardless of the name used for the NOTIFY
    signal in C++. We recommend using <property-name>Changed() for the
    NOTIFY signal in C++.

    We may also make the property a \c read-only property by placing
    \c CONSTANT in the parameter. Changing the binding will generate an error.
\code
//A read-only property
Q_PROPERTY(int size READ size CONSTANT)
\endcode

\section2 Default Property

    When imported, QML components will bind their children to their designated
    \l{default-property}{default property}. This is helpful, for example,
    to redirect any declared child components to a property of another
    component.

    The runtime can set a property to be the default property by tagging the
    property with \c DefaultProperty in The Q_CLASSINFO() macro.

    \code
    Q_CLASSINFO("DefaultProperty", "pipe")
    \endcode

    The property tagged as default property, \c pipe, can only be an object
    property, or a list property.

    A default property is optional. A derived class inherits its base class's
    default property, but may override it in its own declaration. The \c pipe
    property can refer to a property declared in the class itself, or a property
    inherited from a base class.

    The \l{Extending QML - Default Property Example}{Default Property} example
    uses \l{default-property}{default properties} to assign the children of
    a component to a specific property.

    \section2 Grouped Properties

    A property group may be functionally defined as a set of related properties.
    For example, the \l{Layouts with Anchors}{anchors} are a group of
    related properties. In practice, property groups resemble a parent object
    where the individual properties are accessed as children.

    A grouped property's member properties are accessed using the
    <group>.<property> notation. For example, shoe.color is the way to access
    the \c color property in the \c shoe property group .

    \snippet examples/declarative/cppextensions/referenceexamples/grouped/example.qml ungrouped

    Alternatively, the group can be accessed as a set.
    \snippet examples/declarative/cppextensions/referenceexamples/grouped/example.qml grouped

    A grouped property block is implemented as a read-only object property. The
    \c shoe property shown is declared like this:

    \snippet examples/declarative/cppextensions/referenceexamples/grouped/person.h 1

    The \c ShoeDescription type declares the properties available to the grouped
    property block - in this case the \c size, \c color, \c brand and \c price properties.

    Grouped property blocks may declared and accessed be recusively.

    \l {Extending QML - Grouped Properties Example} shows the complete code used to
    implement the \c shoe property grouping.

    \section2 Attached Properties

    Attached properties annotate or add properties to another type or component.
    For example, the \l Keys \e{attaching type} contains \e{attached properties}
    that other elements may use to respond to key input. Conceptually, attached
    properties are a \e type exporting a set of additional properties that can
    be set on any other object instance.

    The attaching type is a QObject derived type. The properties on the
    attaching type are those that become available for use as attached
    properties.

    \snippet examples/declarative/cppextensions/referenceexamples/attached/example.qml 1

    The \c BirthdayParty is called the attaching type and the
    \c Boy instance the attachee object instance. The property \c rsvp is the
    attached property.

    Any Qt C++ type can become an attaching type by declaring the \c
    qmlAttachedProperties() a public member function and declaring that the
    class has QML_HAS_ATTACHED_PROPERTIES.

    \code
    static AttachedPropertiesType *qmlAttachedProperties(QObject *object);
    \endcode

    This static pointer returns an attachment object, of type \a
    AttachedPropertiesType, for the attachee \a object instance. It is
    customary, though not strictly required, for the attachment object to be
    parented to \a object to prevent memory leaks.
    The \l {Extending QML - Attached Properties Example}{Birthday}
    class has \c BirthdayPartyAttached attached properties.

    \snippet examples/declarative/cppextensions/referenceexamples/attached/birthdayparty.h static attached

    The QML_DECLARE_TYPEINFO() macro can notify the runtime that the type has
    attached properties with the QML_HAS_ATTACHED_PROPERTIES argument.

    \snippet examples/declarative/cppextensions/referenceexamples/attached/birthdayparty.h declare attached

    The qmlAttachedProperties method will be called at most once for each
    attachee object instance. The QML engine will cache the returned instance
    pointer for subsequent attached property accesses. Consequently the
    attachment object may not be deleted until \a object is destroyed.

    A common usage scenario is for a type to enhance the properties
    available to its children in order to gather instance specific data.

    \snippet examples/declarative/cppextensions/referenceexamples/attached/example.qml begin
    \snippet examples/declarative/cppextensions/referenceexamples/attached/example.qml rsvp
    \snippet examples/declarative/cppextensions/referenceexamples/attached/example.qml end

    However, as a QML type cannot limit the instances to which the attachment
    object must attach, the following is also allowed, even though adding a
    birthday party rsvp in this context will have no effect. Instead, \c
    BirthdayParty could be a separate component with a property \c rsvp.
    \code
    GraduationParty {
        Boy { BirthdayParty.rsvp: "2009-06-01" }
    }
    \endcode

    From C++, including the attaching type implementation, the attachment object
    for an instance can be accessed using the following method:

    \code
    template<typename T>
    QObject *qmlAttachedPropertiesObject<T>(QObject *attachee, bool create = true);
    \endcode

    This returns the attachment object attached to \a attachee by the attaching
    type \a T. If type \a T is not a valid attaching type, this method always
    returns 0. If \a create is true, a valid attachment object will always be
    returned, creating it if it does not already exist. If \a create is false,
    the attachment object will only be returned if it has previously been
    created.

    The \c rsvp properties of each guest in the \c Birthday party is accessible
    through the \c qmlAttachedPropertiesObject function.

    \snippet examples/declarative/cppextensions/referenceexamples/attached/main.cpp query rsvp

    The
    \l {Extending QML - Attached Properties Example}{Attached Properties Example}
    demonstrates the creation of attached properties with a birthday party
    scenario.

\section2 Object and List Properties

    QML can set properties of types that are more complex than basic intrinsics like
    integers and strings.  Properties can also be object pointers, Qt interface
    pointers,  lists of object pointers, and lists of Qt interface pointers.  As QML
    is typesafe it ensures that only valid types are assigned to these properties,
    just like it does for primitive types.

    Properties that are pointers to objects or Qt interfaces are declared with the
    Q_PROPERTY() macro, just like other properties.  The \c host property
    declaration looks like this:

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

    As long as the property type, in this case \c Person, is registered with QML the
    property can be assigned.

    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

    \c qmlRegisterInterface registers the C++ interface \a T with the QML system
    as \a typeName.

    Following registration, QML can coerce objects that implement this interface
    for assignment to appropriately typed properties.


    \snippet examples/declarative/cppextensions/referenceexamples/properties/example.qml 0

    The \c guests property is a \e{list property} of \c Person objects. A list
    of \c Person objects are bound to the \c BirthdayParty's \c host property,
    and assigns three \c Person objects to the guests property.

    Properties that are lists of objects or Qt interfaces are also declared with
    the Q_PROPERTY() macro. However, list properties must have the type
    \l{QQmlListProperty}{QQmlListProperty<T>}.

    \snippet examples/declarative/cppextensions/referenceexamples/properties/birthdayparty.h 2

    As with the other property types, the type of list content, \a T, must be
    \l{register-c++-type}{registered} into the runtime.

    \snippet examples/declarative/cppextensions/referenceexamples/properties/main.cpp register list

    \l {Extending QML - Object and List Property Types Example} shows the
    complete code used to create the \c BirthdayParty type. For more
    information, visit \l{QQmlListProperty}{QQmlListProperty<T>}
    for creating list properties.

\section2 Sequence Types

    Certain C++ sequence types are supported transparently in QML as JavaScript
    Array types.
    In particular, QML currently supports:
    \list
      \li \c {QList<int>}
      \li \c {QList<qreal>}
      \li \c {QList<bool>}
      \li \c {QList<QString>} and \c{QStringList}
      \li \c {QList<QUrl>}
    \endlist

    These sequence types are implemented directly in terms of the underlying C++
    sequence. There are two ways in which such sequences can be exposed to QML:
    as a Q_PROPERTY of the given sequence type; or as the return type of a
    Q_INVOKABLE method. There are some differences in the way these are
    implemented, which are important to note.

    If the sequence is exposed as a Q_PROPERTY, accessing any value in the
    sequence by index will cause the sequence data to be read from the QObject's
    property, then a read to occur. Similarly, modifying any value in the
    sequence will cause the sequence data to be read, and then the modification
    will be performed and the modified sequence will be written back to the
    QObject's property.

    If the sequence is returned from a Q_INVOKABLE function, access and mutation
    is much cheaper, as no QObject property read or write occurs; instead, the
    C++ sequence data is accessed and modified directly.

    Other sequence types are not supported transparently, and instead an
    instance of any other sequence type will be passed between QML and C++ as an
    opaque QVariantList.

    \b {Important Note:} There are some minor differences between the
    semantics of such sequence Array types and default JavaScript Array types
    which result from the use of a C++ storage type in the implementation. In
    particular, deleting an element from an Array will result in a
    default-constructed value replacing that element, rather than an Undefined
    value. Similarly, setting the length property of the Array to a value larger
    than its current value will result in the Array being padded out to the
    specified length with default-constructed elements rather than Undefined
    elements.  Finally, the Qt container classes support signed (rather than
    unsigned) integer indexes; thus, attempting to access any index greater
    than INT_MAX will fail.

    The default-constructed values for each sequence type are as follows:
    \table
    \row \li QList<int> \li integer value 0
    \row \li QList<qreal> \li real value 0.0
    \row \li QList<bool> \li boolean value \c {false}
    \row \li QList<QString> and QStringList \li empty QString
    \row \li QList<QUrl> \li empty QUrl
    \endtable

    If you wish to remove elements from a sequence rather than simply replace
    them with default constructed values, do not use the indexed delete operator
    ("delete sequence[i]") but instead use the \c {splice} function
    ("sequence.splice(startIndex, deleteCount)").


\section2 Property Signals

    All properties on custom types automatically support property binding.
    However, for binding to work correctly, QML must be able to reliably
    determine when a property has changed so that it knows to reevaluate any
    bindings that depend on the property's value. QML relies on the presence of
    a \l {Qt's Property System}{NOTIFY signal} for this determination.

    Here is the \c host property declaration:

    \snippet examples/declarative/cppextensions/referenceexamples/binding/birthdayparty.h 0

    The NOTIFY attribute is followed by a signal name. It is the responsibility
    of the class implementer to ensure that whenever the property's value
    changes, the NOTIFY signal is emitted. The signature of the NOTIFY signal is
    not important to QML.

    To prevent loops or excessive evaluation, developers should ensure that the
    signal is only emitted whenever the property's value is actually changed. If
    a property, or group of properties, is infrequently used it is permitted to
    use the same NOTIFY signal for several properties. This should be done with
    care to ensure that performance doesn't suffer.

    To keep QML reliable, if a property does not have a NOTIFY signal, it cannot
    be used in a binding expression. However, the property can still be assigned
    a binding as QML does not need to monitor the property for change in that
    scenario.

    Consider a custom type, \c TestElement, that has two properties, \c a and
    \c b. Property \c a does \e not have a NOTIFY signal, and property \c b does
    have a NOTIFY signal.

    \code
    TestElement {
        // This is OK
        a: b
    }
    TestElement {
        // Will NOT work
        b: a
    }
    \endcode

    The presence of a NOTIFY signal does incur a small overhead. There are cases
    where a property's value is set at object construction time, and does not
    subsequently change. The most common case of this is when a type uses \l
    {Grouped Properties}, and the grouped property object is allocated once, and
    only freed when the object is deleted. In these cases, the CONSTANT
    attribute may be added to the property declaration instead of a NOTIFY
    signal.

    \snippet examples/declarative/cppextensions/referenceexamples/binding/person.h 0

    Extreme care must be taken here or applications using your type may misbehave.
    The CONSTANT attribute should only be used for properties whose value is set,
    and finalized, only in the class constructor.  All other properties that want
    to be used in bindings should have a NOTIFY signal instead.

    \l {Extending QML -  Binding Example} shows the BirthdayParty example updated to
    include NOTIFY signals for use in binding.

\section1 Signals Support

    A \l{signals and slots}{signal} in Qt C++ is readily available as a
    \l{QML Signal and Handler Event System}{QML signal}. A signal will have
    a corresponding signal \e{handler}, created automatically. The handler
    name will have \c on prepended at the beginning of the name. The first
    character of the signal is uppercased for the signal handler. The
    signal parameter is also availabe to the QML signal.

    \snippet examples/declarative/cppextensions/referenceexamples/signal/birthdayparty.h 0
    The QML engine will create a handler for the \c partyStarted signal
    called \c onPartyStarted.
    \snippet examples/declarative/cppextensions/referenceexamples/signal/example.qml 0

    Classes may have multiple signals with the same name, but only the final
    signal is accessible as a QML signal. Note that signals with the same name
    but different parameters cannot be distinguished from one another.

    Signal parameters are exposed and can be any one of the QML
    \l{QML Basic Types}{basic types} as well registered object types. Accessing
    unregistered types will not generate an error, but the parameter value will
    not be accessible from the handler.

    To use signals from items not created in QML, access their signals with the
    \l {Connections} element.

    Additionally, if a property is added to a C++ class, all QML elements
    based on that C++ class will have a \e{value-changed} signal handler
    for that property. The name of the signal handler is
    \e{on<Property-name>Changed}, with the first letter of the property
    name being upper case.

    The \l {Extending QML - Signal Support Example}{Signal Support Example}
    shows an example application exposing signals to a QML component.

\section1 Exposing Methods

    The Q_INVOKABLE macro exposes any Qt C++ method as a QML method.

    \snippet examples/declarative/cppextensions/referenceexamples/methods/birthdayparty.h 0

    In a QML file, we can invoke the method as we would a
    \l{JavaScript Expressions in QML}{JavaScript expression}.
    \snippet examples/declarative/cppextensions/referenceexamples/methods/example.qml 0

    \l {Extending QML - Methods Example}{Methods example} uses the Q_INVOKABLE
    method to expose methods and demonstrates some usages of the method in
    an application.

    An alternative to the Q_INVOKABLE macro is to declare the C++ method as a
    \l{signals and slot}{slot}.

    \code
    slots:
        void invite(const QString &name);
    \endcode


*/