source: trunk/doc/src/declarative/extending.qdoc@ 846

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 45.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:FDL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in a
14** written agreement between you and Nokia.
15**
16** GNU Free Documentation License
17** Alternatively, this file may be used under the terms of the GNU Free
18** Documentation License version 1.3 as published by the Free Software
19** Foundation and appearing in the file included in the packaging of this
20** file.
21**
22** If you have questions regarding the use of this file, please contact
23** Nokia at qt-info@nokia.com.
24** $QT_END_LICENSE$
25**
26****************************************************************************/
27
28/*!
29\page qml-extending.html
30\title Extending QML in C++
31
32The QML syntax declaratively describes how to construct an in-memory object
33tree. In Qt, QML is mainly used to describe a visual scene graph, but it is
34not conceptually limited to this: the QML format is an abstract description of
35any object tree. All the QML element types included in Qt are implemented using
36the C++ extension mechanisms describe on this page. Programmers can use these
37APIs to add new types that interact with the existing Qt types, or to repurpose
38QML for their own independent use.
39
40\tableofcontents
41
42\section1 Adding Types
43\target adding-types
44
45\snippet examples/declarative/cppextensions/referenceexamples/adding/example.qml 0
46
47The QML snippet shown above instantiates one \c Person instance and sets
48the \c name and \c shoeSize properties on it. Everything in QML ultimately comes down
49to either instantiating an object instance, or assigning a property a value.
50
51QML relies heavily on Qt's meta object system and can only instantiate classes
52that derive from QObject. For visual element types, this will usually mean a subclass
53of QDeclarativeItem; for models used with the view elements, a subclass of QAbstractItemModel;
54and for abitrary objects with properties, a direct subclass of QObject.
55
56The QML engine has no intrinsic knowledge of any class types. Instead the
57programmer must register the C++ types with their corresponding QML names.
58
59Custom C++ types are registered using a template function:
60
61\quotation
62
63\code
64template<typename T>
65int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
66\endcode
67
68Calling qmlRegisterType() registers the C++ type \a T with the QML
69system, and makes it available in QML under the name \a qmlName in
70library \a uri version \a versionMajor.versionMinor. The \a qmlName
71can be the same as the C++ type name.
72
73Type \a T must be a concrete type that inherits QObject and has a default
74constructor.
75
76\endquotation
77
78#include <QtDeclarative> to use qmlRegisterType().
79
80Types can be registered by libraries, application code, or by plugins
81(see QDeclarativeExtensionPlugin).
82
83Once registered, all \l {Qt's Property System}{properties} of the
84supported types are available in QML. QML has intrinsic support for
85properties of the types listed in the \l{Adding Properties}
86document, which includes the following:
87
88\list
89\o bool, unsigned int, int, float, double, qreal
90\o QString, QUrl, QColor
91\o QDate, QTime, QDateTime
92\o QPoint, QPointF, QSize, QSizeF, QRect, QRectF
93\o QVariant
94\endlist
95
96When a property of a supported type is added to a C++ class, in a QML
97element based on the C++ class, a \e{value-changed} signal handler
98will be available. See \l{Signal Support} below.
99
100QML is typesafe. Attempting to assign an invalid value to a property
101will generate an error. For example, assuming the \e{name} property
102of the \c Person element had a type of QString, this would cause an
103error:
104
105\code
106Person {
107 // Will NOT work
108 name: 12
109}
110\endcode
111
112\l {Extending QML - Adding Types Example} shows the complete code used to create
113the \c Person type.
114
115\section1 Object and List Property Types
116
117\snippet examples/declarative/cppextensions/referenceexamples/properties/example.qml 0
118
119The QML snippet shown above assigns a \c Person object to the \c BirthdayParty's
120\c host property, and assigns three \c Person objects to the guests property.
121
122QML can set properties of types that are more complex than basic intrinsics like
123integers and strings. Properties can also be object pointers, Qt interface
124pointers, lists of object points, and lists of Qt interface pointers. As QML
125is typesafe it ensures that only valid types are assigned to these properties,
126just like it does for primitive types.
127
128Properties that are pointers to objects or Qt interfaces are declared with the
129Q_PROPERTY() macro, just like other properties. The \c host property
130declaration looks like this:
131
132\snippet examples/declarative/cppextensions/referenceexamples/properties/birthdayparty.h 1
133
134As long as the property type, in this case \c Person, is registered with QML the
135property can be assigned.
136
137QML also supports assigning Qt interfaces. To assign to a property whose type
138is a Qt interface pointer, the interface must also be registered with QML. As
139they cannot be instantiated directly, registering a Qt interface is different
140from registering a new QML type. The following function is used instead:
141
142\quotation
143\code
144template<typename T>
145int qmlRegisterInterface(const char *typeName)
146\endcode
147
148This registers the C++ interface \a T with the QML system as \a typeName.
149
150Following registration, QML can coerce objects that implement this interface
151for assignment to appropriately typed properties.
152\endquotation
153
154The \c guests property is a list of \c Person objects. Properties that are lists
155of objects or Qt interfaces are also declared with the Q_PROPERTY() macro, just
156like other properties. List properties must have the type \c {QDeclarativeListProperty<T>}.
157As with object properties, the type \a T must be registered with QML.
158
159The \c guest property declaration looks like this:
160
161\snippet examples/declarative/cppextensions/referenceexamples/properties/birthdayparty.h 2
162
163\l {Extending QML - Object and List Property Types Example} shows the complete
164code used to create the \c BirthdayParty type.
165
166\section1 Inheritance and Coercion
167
168\snippet examples/declarative/cppextensions/referenceexamples/coercion/example.qml 0
169
170The QML snippet shown above assigns a \c Boy object to the \c BirthdayParty's
171\c host property, and assigns three other objects to the \c guests property.
172
173QML supports C++ inheritance hierarchies and can freely coerce between known,
174valid object types. This enables the creation of common base classes that allow
175the assignment of specialized classes to object or list properties. In the
176snippet shown, both the \c host and the \c guests properties retain the \c Person
177type used in the previous section, but the assignment is valid as both the \c Boy
178and \c Girl objects inherit from \c Person.
179
180To assign to a property, the property's type must have been registered with QML.
181Both the qmlRegisterType() and qmlRegisterInterface() template functions already
182shown can be used to register a type with QML. Additionally, if a type that acts purely
183as a base class that cannot be instantiated from QML needs to be
184registered, the following function can be used:
185
186\quotation
187\code
188 template<typename T>
189 int qmlRegisterType()
190\endcode
191
192This registers the C++ type \a T with the QML system. The parameterless call to the template
193function qmlRegisterType() does not define a mapping between the
194C++ class and a QML element name, so the type is not instantiable from QML, but
195it is available for type coercion.
196
197Type \a T must inherit QObject, but there are no restrictions on whether it is
198concrete or the signature of its constructor.
199\endquotation
200
201QML will automatically coerce C++ types when assigning to either an object
202property, or to a list property. Only if coercion fails does an assignment
203error occur.
204
205\l {Extending QML - Inheritance and Coercion Example} shows the complete
206code used to create the \c Boy and \c Girl types.
207
208\section1 Default Property
209
210\snippet examples/declarative/cppextensions/referenceexamples/default/example.qml 0
211
212The QML snippet shown above assigns a collection of objects to the
213\c BirthdayParty's default property.
214
215The \e {default property} is a syntactic convenience that allows a type designer to
216specify a single property as the type's default. The default property is
217assigned to whenever no explicit property is specified. As a convenience, it is
218behaviorally identical to assigning to the default property explicitly by name.
219
220From C++, type designers mark the default property using a Q_CLASSINFO()
221annotation:
222
223\quotation
224\code
225Q_CLASSINFO("DefaultProperty", "property")
226\endcode
227
228This marks \a property as the class's default property. \a property must be either
229an object property, or a list property.
230
231A default property is optional. A derived class inherits its base class's
232default property, but may override it in its own declaration. \a property can
233refer to a property declared in the class itself, or a property inherited from a
234base class.
235\endquotation
236
237\l {Extending QML - Default Property Example} shows the complete code used to
238specify a default property.
239
240\section1 Grouped Properties
241
242\snippet examples/declarative/cppextensions/referenceexamples/grouped/example.qml 1
243
244The QML snippet shown above assigns a number of properties to the \c Boy object,
245including four properties using the grouped property syntax.
246
247Grouped properties collect similar properties together into a single named
248block. Grouped properties can be used to present a nicer API to developers, and
249may also simplify the implementation of common property collections across
250different types through implementation reuse.
251
252A grouped property block is implemented as a read-only object property. The
253\c shoe property shown is declared like this:
254
255\snippet examples/declarative/cppextensions/referenceexamples/grouped/person.h 1
256
257The \c ShoeDescription type declares the properties available to the grouped
258property block - in this case the \c size, \c color, \c brand and \c price properties.
259
260Grouped property blocks may declared and accessed be recusively.
261
262\l {Extending QML - Grouped Properties Example} shows the complete code used to
263implement the \c shoe property grouping.
264
265\section1 Attached Properties
266
267\snippet examples/declarative/cppextensions/referenceexamples/attached/example.qml 1
268
269The QML snippet shown above assigns a date to the \c rsvp property using the attached
270property syntax.
271
272Attached properties allow unrelated types to annotate other types with some
273additional properties, generally for their own use. Attached properties are
274identified through the use of the attacher type name, in the case shown
275\c BirthdayParty, as a prefix to the property name.
276
277In the example shown, \c BirthdayParty is called the attaching type, and the
278\c Boy instance the attachee object instance.
279
280For the attaching type, an attached property block is implemented as a new
281QObject derived type, called the attachment object. The properties on the
282attachment object are those that become available for use as the attached
283property block.
284
285Any QML type can become an attaching type by declaring the
286\c qmlAttachedProperties() public function and declaring that the class has
287QML_HAS_ATTACHED_PROPERTIES:
288
289\quotation
290\code
291class MyType : public QObject {
292 Q_OBJECT
293public:
294
295 ...
296
297 static AttachedPropertiesType *qmlAttachedProperties(QObject *object);
298};
299
300QML_DECLARE_TYPEINFO(MyType, QML_HAS_ATTACHED_PROPERTIES)
301\endcode
302This returns an attachment object, of type \a AttachedPropertiesType, for the
303attachee \a object instance. It is customary, though not strictly required, for
304the attachment object to be parented to \a object to prevent memory leaks.
305
306\a AttachedPropertiesType must be a QObject derived type. The properties on
307this type will be accessible through the attached properties syntax.
308
309This method will be called at most once for each attachee object instance. The
310QML engine will cache the returned instance pointer for subsequent attached
311property accesses. Consequently the attachment object may not be deleted until
312\a object is destroyed.
313\endquotation
314
315Conceptually, attached properties are a \e type exporting a set of additional
316properties that can be set on \e any other object instance. Attached properties
317cannot be limited to only attaching to a sub-set of object instances, although
318their effect may be so limited.
319
320For example, a common usage scenario is for a type to enhance the properties
321available to its children in order to gather instance specific data. Here we
322add a \c rsvp field to all the guests coming to a birthday party:
323\code
324BirthdayParty {
325 Boy { BirthdayParty.rsvp: "2009-06-01" }
326}
327\endcode
328However, as a type cannot limit the instances to which the attachment object
329must attach, the following is also allowed, even though adding a birthday party
330rsvp in this context will have no effect.
331\code
332GraduationParty {
333 Boy { BirthdayParty.rsvp: "2009-06-01" }
334}
335\endcode
336
337From C++, including the attaching type implementation, the attachment object for
338an instance can be accessed using the following method:
339
340\quotation
341\code
342template<typename T>
343QObject *qmlAttachedPropertiesObject<T>(QObject *attachee, bool create = true);
344\endcode
345This returns the attachment object attached to \a attachee by the attaching type
346\a T. If type \a T is not a valid attaching type, this method always returns 0.
347
348If \a create is true, a valid attachment object will always be returned,
349creating it if it does not already exist. If \a create is false, the attachment
350object will only be returned if it has previously been created.
351\endquotation
352
353\l {Extending QML - Attached Properties Example} shows the complete code used to
354implement the rsvp attached property.
355
356\section1 Memory Management and QVariant types
357
358It is an element's responsibility to ensure that it does not access or return
359pointers to invalid objects. QML makes the following guarentees:
360
361\list
362\o An object assigned to a QObject (or QObject-derived) pointer property will be
363valid at the time of assignment.
364
365Following assignment, it is the responsibility of the class to subsequently guard
366this pointer, either through a class specific method or the generic QPointer class.
367
368\o An object assigned to a QVariant will be valid at the time of assignment.
369
370When assigning an object to a QVariant property, QML will always use a QMetaType::QObjectStar
371typed QVariant. It is the responsibility of the class to guard the pointer. A
372general rule when writing a class that uses QVariant properties is to check the
373type of the QVariant when it is set and if the type is not handled by your class,
374reset it to an invalid variant.
375
376\o An object assigned to a QObject (or QObject-derived) list property will be
377valid at the time of assignment.
378
379Following assignment, it is the responsibility of the class to subsequently guard
380this pointer, either through a class specific method or the generic QPointer class.
381\endlist
382
383Elements should assume that any QML assigned object can be deleted at any time, and
384respond accordingly. If documented as such an element need not continue to work in
385this situation, but it must not crash.
386
387\section1 Signal Support
388
389\snippet examples/declarative/cppextensions/referenceexamples/signal/example.qml 0
390\snippet examples/declarative/cppextensions/referenceexamples/signal/example.qml 1
391
392The QML snippet shown above associates the evaluation of a JavaScript expression
393with the emission of a Qt signal.
394
395All Qt signals on a registered class become available as special "signal
396properties" within QML to which the user can assign a single JavaScript
397expression. The signal property's name is a transformed version of the Qt
398signal name: "on" is prepended, and the first letter of the signal name upper
399cased. For example, the signal used in the example above has the following
400C++ signature:
401
402\snippet examples/declarative/cppextensions/referenceexamples/signal/birthdayparty.h 0
403
404In classes with multiple signals with the same name, only the final signal
405is accessible as a signal property. Note that signals with the same name
406but different parameters cannot be distinguished.
407
408Signal parameters become accessible by name to the assigned script. An
409unnamed parameter cannot be accessed, so care should be taken to name all the
410signal parameters in the C++ class declaration. The intrinsic types
411listed in \l {Adding Types}, as well registered object types are permitted as
412signal parameter types. Using other types is not an error, but the parameter
413value will not be accessible from script.
414
415\l {Extending QML - Signal Support Example} shows the complete code used to
416implement the onPartyStarted signal property.
417
418If you want to use signals from items not created in QML, you can access their
419signals with the \l {Connections} element.
420
421Additionally, if a property is added to a C++ class, all QML elements
422based on that C++ class will have a \e{value-changed} signal handler
423for that property. The name of the signal handler is
424\e{on<Property-name>Changed}, with the first letter of the property
425name being upper case.
426
427\note The QML signal handler will always be named
428on<Property-name>Changed, regardless of the name used for the NOTIFY
429signal in C++. We recommend using <property-name>Changed() for the
430NOTIFY signal in C++.
431
432See also \l {Writing QML Components: Properties, Methods and Signals}
433
434\section1 Methods
435
436Slots and methods marked Q_INVOKABLE may be called as functions in QML.
437
438\snippet examples/declarative/cppextensions/referenceexamples/methods/example.qml 0
439
440In this example an invitation is added via an \c {invite()} invokable method of
441the BirthdayParty element. This function is available in QML by marking the \c {invite()}
442method with Q_INVOKABLE in the BirthdayParty class:
443
444\snippet examples/declarative/cppextensions/referenceexamples/methods/birthdayparty.h 0
445
446\l {Extending QML - Methods Example} shows the complete code used to
447implement the invite() method.
448
449The \c {invite()} method is similarly available if it is declared as a slot.
450
451\section1 Property Value Sources
452
453\snippet examples/declarative/cppextensions/referenceexamples/valuesource/example.qml 0
454\snippet examples/declarative/cppextensions/referenceexamples/valuesource/example.qml 1
455
456The QML snippet shown above applies a property value source to the \c announcment property.
457A property value source generates a value for a property that changes over time.
458
459Property value sources are most commonly used to do animation. Rather than
460constructing an animation object and manually setting the animation's "target"
461property, a property value source can be assigned directly to a property of any
462type and automatically set up this association.
463
464The example shown here is rather contrived: the \c announcement property of the
465\c BirthdayParty object is a string that is printed every time it is assigned and
466the \c HappyBirthdaySong value source generates the lyrics of the song
467"Happy Birthday".
468
469\snippet examples/declarative/cppextensions/referenceexamples/valuesource/birthdayparty.h 0
470
471Normally, assigning an object to a string property would not be allowed. In
472the case of a property value source, rather than assigning the object instance
473itself, the QML engine sets up an association between the value source and
474the property.
475
476Property value sources are special types that derive from the
477QDeclarativePropertyValueSource base class. This base class contains a single method,
478QDeclarativePropertyValueSource::setTarget(), that the QML engine invokes when
479associating the property value source with a property. The relevant part of
480the \c HappyBirthdaySong type declaration looks like this:
481
482\snippet examples/declarative/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 0
483\snippet examples/declarative/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 1
484\snippet examples/declarative/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 2
485
486In all other respects, property value sources are regular QML types. They must
487be registered with the QML engine using the same macros as other types, and can
488contain properties, signals and methods just like other types.
489
490When a property value source object is assigned to a property, QML first tries
491to assign it normally, as though it were a regular QML type. Only if this
492assignment fails does the engine call the \l {QDeclarativePropertyValueSource::}{setTarget()} method. This allows
493the type to also be used in contexts other than just as a value source.
494
495\l {Extending QML - Property Value Source Example} shows the complete code used
496implement the \c HappyBirthdaySong property value source.
497
498\section1 Property Binding
499
500\snippet examples/declarative/cppextensions/referenceexamples/binding/example.qml 0
501\snippet examples/declarative/cppextensions/referenceexamples/binding/example.qml 1
502
503The QML snippet shown above uses a property binding to ensure the
504\c HappyBirthdaySong's \c name property remains up to date with the \c host.
505
506Property binding is a core feature of QML. In addition to assigning literal
507values, property bindings allow the developer to assign an arbitrarily complex
508JavaScript expression that may include dependencies on other property values.
509Whenever the expression's result changes - through a change in one of its
510constituent values - the expression is automatically reevaluated and
511the new result assigned to the property.
512
513All properties on custom types automatically support property binding. However,
514for binding to work correctly, QML must be able to reliably determine when a
515property has changed so that it knows to reevaluate any bindings that depend on
516the property's value. QML relies on the presence of a
517\l {Qt's Property System}{NOTIFY signal} for this determination.
518
519Here is the \c host property declaration:
520
521\snippet examples/declarative/cppextensions/referenceexamples/binding/birthdayparty.h 0
522
523The NOTIFY attribute is followed by a signal name. It is the responsibility of
524the class implementer to ensure that whenever the property's value changes, the
525NOTIFY signal is emitted. The signature of the NOTIFY signal is not important to QML.
526
527To prevent loops or excessive evaluation, developers should ensure that the
528signal is only emitted whenever the property's value is actually changed. If
529a property, or group of properties, is infrequently used it is permitted to use
530the same NOTIFY signal for several properties. This should be done with care to
531ensure that performance doesn't suffer.
532
533To keep QML reliable, if a property does not have a NOTIFY signal, it cannot be
534used in a binding expression. However, the property can still be assigned
535a binding as QML does not need to monitor the property for change in that
536scenario.
537
538Consider a custom type, \c TestElement, that has two properties, "a" and "b".
539Property "a" does not have a NOTIFY signal, and property "b" does have a NOTIFY
540signal.
541
542\code
543TestElement {
544 // This is OK
545 a: b
546}
547TestElement {
548 // Will NOT work
549 b: a
550}
551\endcode
552
553The presence of a NOTIFY signal does incur a small overhead. There are cases
554where a property's value is set at object construction time, and does not
555subsequently change. The most common case of this is when a type uses
556\l {Grouped Properties}, and the grouped property object is allocated once, and
557only freed when the object is deleted. In these cases, the CONSTANT attribute
558may be added to the property declaration instead of a NOTIFY signal.
559
560\snippet examples/declarative/cppextensions/referenceexamples/binding/person.h 0
561
562Extreme care must be taken here or applications using your type may misbehave.
563The CONSTANT attribute should only be used for properties whose value is set,
564and finalized, only in the class constructor. All other properties that want
565to be used in bindings should have a NOTIFY signal instead.
566
567\l {Extending QML - Binding Example} shows the BirthdayParty example updated to
568include NOTIFY signals for use in binding.
569
570\section1 Extension Objects
571
572\snippet examples/declarative/cppextensions/referenceexamples/extended/example.qml 0
573
574The QML snippet shown above adds a new property to an existing C++ type without
575modifying its source code.
576
577When integrating existing classes and technology into QML, their APIs will often
578need to be tweaked to fit better into the declarative environment. Although
579the best results are usually obtained by modifying the original classes
580directly, if this is either not possible or is complicated by some other
581concerns, extension objects allow limited extension possibilities without
582direct modifications.
583
584Extension objects are used to add additional properties to an existing type.
585Extension objects can only add properties, not signals or methods. An extended
586type definition allows the programmer to supply an additional type - known as the
587extension type - when registering the target class whose properties are
588transparently merged with the original target class when used from within QML.
589
590An extension class is a regular QObject, with a constructor that takes a QObject
591pointer. When needed (extension class creation is delayed until the first extended
592property is accessed) the extension class is created and the target object is
593passed in as the parent. When an extended property on the original is accessed,
594the appropriate property on the extension object is used instead.
595
596When an extended type is installed, one of the
597\code
598template<typename T, typename ExtendedT>
599int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
600
601template<typename T, typename ExtendedT>
602int qmlRegisterExtendedType()
603\endcode
604functions should be used instead of the regular \c qmlRegisterType() variations.
605The arguments are identical to the corresponding non-extension registration functions,
606except for the ExtendedT parameter which is the type
607of the extension object.
608
609\section1 Optimization
610
611Often to develop high performance elements it is helpful to know more about the
612status of the QML engine. For example, it might be beneficial to delay
613initializing some costly data structures until after all the properties have been
614set.
615
616The QML engine defines an interface class called QDeclarativeParserStatus, which contains a
617number of virtual methods that are invoked at various stages during component
618instantiation. To receive these notifications, an element implementation inherits
619QDeclarativeParserStatus and notifies the Qt meta system using the Q_INTERFACES() macro.
620
621For example,
622
623\code
624class Example : public QObject, public QDeclarativeParserStatus
625{
626 Q_OBJECT
627 Q_INTERFACES(QDeclarativeParserStatus)
628public:
629 virtual void componentComplete()
630 {
631 qDebug() << "Woohoo! Now to do my costly initialization";
632 }
633};
634\endcode
635
636*/
637
638/*!
639\page qml-extending-types.html
640\title Writing QML Components: Properties, Methods and Signals
641
642One of the key concepts in QML is the ability to define your own QML components that suit
643the purposes of your application. The standard \l {QML Elements} provide the essential components
644for creating a QML application; beyond these, you can write your own custom components that can
645be created and reused, without the use of C++.
646
647Components are the building blocks of a QML project. When writing a QML application, whether
648large or small, it is best to separate QML code into smaller components that perform specific
649sets of operations, instead of creating mammoth QML files with large, combined functionality
650that is more difficult to manage and may contain duplicated code.
651
652
653\section1 Defining New Components
654
655A component is a reusable type with a well-defined interface, built entirely in QML.
656Any snippet of QML code can become a component, by placing the code in a file "<Name>.qml" where
657<Name> is the new component name, beginning with an uppercase letter. These QML files automatically
658become available as new QML element types to other QML components and applications in the same directory.
659
660For example, one of the simplest and most common components you can build in QML is a
661button-type component. Below, we implement this component as a \l Rectangle with a clickable
662\l MouseArea, in a file named \c Button.qml:
663
664\snippet doc/src/snippets/declarative/qml-extending-types/components/Button.qml 0
665
666Now this component can be reused by another file within the same directory. Since the file is
667named \c Button.qml, the component is referred to as \c Button:
668
669\table
670\row
671\o \snippet doc/src/snippets/declarative/qml-extending-types/components/application.qml 0
672\o \image qml-extending-types.png
673\endtable
674
675The root object in \c Button.qml defines the attributes that are available to users of the
676\c Button component. In this case, the root object is a \l Rectangle, so any properties, methods
677and signals of \l Rectangle are made available, allowing \c application.qml to
678customize the \c width, \c height, \c radius and \c color properties of \c Button objects.
679
680
681If \c Button.qml was not in the same directory, \c application.qml would need to load it as a
682\l {Modules}{module} from a specific filesystem path or \l{QDeclarativeExtensionPlugin}{plugin}.
683Also, note the letter case of the component file name is significant on some (notably UNIX)
684filesystems. It is recommended the file name case matches the case of the QML component name
685exactly - for example, \c Box.qml and not \c BoX.qml - regardless of the platform to which the
686QML component will be deployed.
687
688To write a useful component, it is generally necessary to provide it with custom attributes that store and
689communicate specific data. This is achieved by adding the following attributes to your components:
690
691\list
692\o \bold Properties that can be accessed externally to modify an object (for example, \l Item has
693 \l {Item::}{width} and \l {Item::}{height} properties) and used in \l {Property Binding}
694\o \bold Methods of JavaScript code can be invoked internally or externally (for example,
695 \l Animation has a \l {Animation::}{start()} method)
696\o \bold Signals to notify other objects when an event has occurred (for example, MouseArea has a
697 \c clicked signal)
698\endlist
699
700The following sections show how these attributes can be added to QML components.
701
702
703\section1 Adding Properties
704
705A property is a value of a QML component that can be read and modified by other objects. For
706example, a \l Rectangle component has \l {Item::}{width}, \l {Item::}{height} and \l
707{Rectangle::}{color} properties. Significantly, properties be used with \l {Property Binding}, where
708a property value is automatically updated using the value of another property.
709
710The syntax for defining a new property is:
711
712\code
713[default] property <type> <name>[: defaultValue]
714\endcode
715
716A \c property declaration can appear anywhere within a QML component definition, but it is customary
717to place it at the top. A component cannot declare more than one property with the same name. (It is
718possible to have a property name that is the same as an existing property in a type, but this is not
719recommended as the existing property becomes hidden and inaccessible.)
720
721Below is an example. The \c ImageViewer component has defined a \c string type property named
722\c currentImage, and its initial value is "default-image.png". This property is used to set the image
723displayed in the child \l Image object. Another file, \c application.qml, can create
724an \c ImageViewer object and read or modify the \c currentImage value:
725
726\table
727\row
728\o \snippet doc/src/snippets/declarative/qml-extending-types/properties/ImageViewer.qml 0
729\o \snippet doc/src/snippets/declarative/qml-extending-types/properties/application.qml 0
730\endtable
731
732It is optional for a property to have a default value. The default value is a convenient shortcut, and is
733behaviorally identical to doing it in two steps, like this:
734
735\qml
736// Use default value
737property int myProperty: 10
738
739// Longer, but behaviorally identical
740property int myProperty
741myProperty: 10
742\endqml
743
744
745\section2 Supported property types
746
747All QML properties are typed. The examples above show properties with \c int and \c string types;
748notice that the type of the property must be declared. The type is used to determine the property
749behavior, and how the property is defined in C++.
750
751A number of property types are supported by default. These are listed in the table below,
752with their default values and the corresponding C++ type:
753
754\table
755\header \o QML Type Name \o Default value \o C++ Type Name
756\row \o \l int \o 0 \o int
757\row \o \l bool \o \c false \o bool
758\row \o \l double \o 0.0 \o double
759\row \o \l real \o 0.0 \o double
760\row \o \l string \o "" (empty string) \o QString
761\row \o \l url \o "" (empty url) \o QUrl
762\row \o \l color \o #000000 (black) \o QColor
763\row \o \l date \o \c undefined \o QDateTime
764\row \o \l variant \o \c undefined \o QVariant
765\endtable
766
767QML object types can also be used as property types. This includes
768\l {Defining new QML elements}{custom QML types} implemented in C++. Such properties are
769defined like this:
770
771\qml
772property Item itemProperty
773property QtObject objectProperty
774property MyCustomType customProperty
775\endqml
776
777Such object-type properties default to an \c undefined value.
778
779It is also possible to store a copy of a JavaScript object using the \c variant
780property type. This creates some restrictions on how the property should be used;
781see the \l {variant}{variant type documentation} for details.
782
783\l{list}{List properties} are created with the \c list<Type> syntax, and default to an empty
784list:
785
786\qml
787property list<Item> listOfItems
788\endqml
789
790Note that list properties cannot be modified like ordinary JavaScript
791arrays. See the \l {list}{list type documentation} for details.
792
793
794\section2 Property change signals
795
796Adding a \c property to an item automatically adds a \e {value changed}
797signal handler to the item. To connect to this signal, use a \l {Signal Handlers}{signal handler}
798named with the \c on<Property>Changed syntax, using upper case for the first letter of the
799property name.
800
801For example, the following \c onMyNumberChanged signal handler is automatically called whenever the
802\c myNumber property changes:
803
804\snippet doc/src/snippets/declarative/qml-extending-types/properties/property-signals.qml 0
805
806
807\section2 Default properties
808
809The optional \c default attribute for a property marks it as the \e {default property}
810for a type. This allows other items to specify the default property's value
811as child elements. For example, the \l Item element's default property is its
812\l{Item::children}{children} property. This allows the children of an \l Item
813to be set like this:
814
815\qml
816Item {
817 Rectangle {}
818 Rectangle {}
819}
820\endqml
821
822If the \l{Item::children}{children} property was not the default property for
823\l Item, its value would have to be set like this instead:
824
825\qml
826Item {
827 children: [
828 Rectangle {}
829 Rectangle {}
830 ]
831}
832\endqml
833
834See the \l{declarative/ui-components/tabwidget}{TabWidget} example for a
835demonstration of using default properties.
836
837Specifying a default property overrides any existing default property (for
838example, any default property inherited from a parent item). Using the
839\c default attribute twice in the same type block is an error.
840
841
842\section2 Property aliases
843
844Property aliases are a more advanced form of property declaration. Unlike a
845property definition, which allocates a new, unique storage space for the
846property, a property alias connects the newly declared property (called the
847aliasing property) as a direct reference to an existing property (the aliased property). Read
848operations on the aliasing property act as read operations on the aliased
849property, and write operations on the aliasing property as write operations on
850the aliased property.
851
852A property alias declaration looks a lot like an ordinary property definition:
853\code
854 [default] property alias <name>: <alias reference>
855\endcode
856
857As the aliasing property has the same type as the aliased property, an explicit
858type is omitted, and the special "alias" keyword is used. Instead of a default
859value, a property alias includes a compulsory alias reference. The alias
860reference is used to locate the aliased property. While similar to a property
861binding, the alias reference syntax is highly restricted.
862
863An alias reference takes one of the following forms:
864\code
865 <id>.<property>
866 <id>
867\endcode
868
869where <id> must refer to an object id within the same component as the type
870declaring the alias, and, optionally, <property> refers to a property on that object.
871
872For example, below is a \c Button.qml component with a \c buttonText aliased property which is
873connected to the child Text object's \c text property:
874
875\snippet doc/src/snippets/declarative/qml-extending-types/properties/alias.qml 0
876
877The following code would create a \c Button with a defined text string for the
878child \l Text object:
879
880\qml
881Button { buttonText: "This is a button" }
882\endqml
883
884Here, modifying \c buttonText directly modifies the \c textItem.text value; it does not
885change some other value that then updates \c textItem.text.
886
887In this case, the use of aliased properties is essential. If \c buttonText was not an alias,
888changing its value would not actually change the displayed text at all, as
889\l {Property Binding}{property bindings} are not bi-directional: the \c buttonText value would
890change when \c textItem.text changes, but not the other way around.
891
892Aliased properties are also useful for allowing external objects to directly modify and
893access child objects in a component. For example, here is a modified version of the \c ImageViewer
894component shown \l {Adding Properties}{earlier} on this page. The \c currentImage property has
895been changed to an alias to the child \l Image object:
896
897\table
898\row
899\o \snippet doc/src/snippets/declarative/qml-extending-types/properties/alias/ImageViewer.qml 0
900\o \snippet doc/src/snippets/declarative/qml-extending-types/properties/alias/application.qml 0
901\endtable
902
903Instead of being limited to setting the \l Image source, \c application.qml can now directly
904access and modify the child \l Image object and its properties.
905
906Obviously, exposing child objects in this manner should be done with care, as it allows external
907objects to modify them freely. However, this use of aliased properties can be quite useful in
908particular situations, such as for the \l {declarative/ui-components/tabwidget}{TabWidget}
909example, where new tab items are actually parented to a child object that displays the current tab.
910
911
912\section3 Considerations for property aliases
913
914Aliases are only activated once the component specifying them is completed. The
915most obvious consequence of this is that the component itself cannot generally
916use the aliased property directly during creation. For example, this will not work:
917
918\code
919 // Does NOT work
920 property alias buttonText: textItem.text
921 buttonText: "Some text" // buttonText is not yet defined when this value is set
922\endcode
923
924A second, much less significant, consequence of the delayed activation of
925aliases is that an alias reference cannot refer to another aliasing property
926declared within the same component. This will not work:
927
928\code
929 // Does NOT work
930 id: root
931 property alias buttonText: textItem.text
932 property alias buttonText2: root.buttonText
933\endcode
934
935At the time the component is created, the \c buttonText value has not yet been assigned,
936so \c root.buttonText would refer to an undefined value. (From outside the component,
937however, aliasing properties appear as regular Qt properties and consequently can be
938used in alias references.)
939
940It is possible for an aliased property to have the same name as an existing property. For example,
941the following component has a \c color alias property, named the same as the built-in
942\l {Rectangle::color} property:
943
944\snippet doc/src/snippets/declarative/qml-extending-types/properties/alias-override.qml 0
945
946Any objects that use this component and refer to its \c color property will be
947referring to the alias rather than the ordinary \l {Rectangle::color} property. Internally,
948however, the rectangle can correctly set this property to "red" and refer to the actual defined
949property rather than the alias.
950
951
952\section1 Adding Methods
953
954A QML component can define methods of JavaScript code. These methods can be invoked
955either internally or by other objects.
956
957The syntax for defining a method is:
958
959\code
960function <name>([<parameter name>[, ...]]) { <body> }
961\endcode
962
963This declaration may appear anywhere within a type body, but it is customary to
964include it at the top. Attempting to declare two methods or signals with the
965same name in the same type block is an error. However, a new method may reuse
966the name of an existing method on the type. (This should be done with caution,
967as the existing method may be hidden and become inaccessible.)
968
969Unlike \l{Adding Signals}{signals}, method parameter types do not have to be declared as they
970default to the \c variant type. The body of the method is written in JavaScript and may access
971the parameters by name.
972
973Here is an example of a component with a \c say() method that accepts a single \c text argument:
974
975\snippet doc/src/snippets/declarative/qml-extending-types/methods/app.qml 0
976
977A method can be connected to a signal so that it is automatically invoked whenever the signal
978is emitted. See \l {Connecting signals to methods and other signals} below.
979
980Also see \l {Integrating JavaScript} for more information on using JavaScript with QML.
981
982
983\section1 Adding Signals
984
985Signals provide a way to notify other objects when an event has occurred. For example, the MouseArea
986\c clicked signal notifies other objects that the mouse has been clicked within the area.
987
988The syntax for defining a new signal is:
989
990\code
991signal <name>[([<type> <parameter name>[, ...]])]
992\endcode
993
994This declaration may appear anywhere within a type body, but it is customary to
995include it at the top. Attempting to declare two signals or methods with the
996same name in the same type block is an error. However, a new signal may reuse
997the name of an existing signal on the type. (This should be done with caution,
998as the existing signal may be hidden and become inaccessible.)
999
1000Here are three examples of signal declarations:
1001
1002\code
1003Item {
1004 signal clicked
1005 signal hovered()
1006 signal performAction(string action, variant actionArgument)
1007}
1008\endcode
1009
1010If the signal has no parameters, the "()" brackets are optional. If parameters are used, the
1011parameter types must be declared, as for the \c string and \c variant arguments for the \c
1012performAction signal above; the allowed parameter types are the same as those listed in the \l
1013{Adding Properties} section on this page.
1014
1015Adding a signal to an item automatically adds a \l {Signal Handlers}{signal handler} as well.
1016The signal hander is named \c on<SignalName>, with the first letter of the signal being upper
1017cased. The above example item would now have the following signal handlers:
1018
1019\list
1020\o onClicked
1021\o onHovered
1022\o onPerformAction
1023\endlist
1024
1025To emit a signal, simply invoke it in the same way as a method. Below left, when the \l MouseArea is
1026clicked, it emits the parent \c buttonClicked signal by invoking \c rect.buttonClicked(). The
1027signal is received by \c application.qml through an \c onButtonClicked signal handler:
1028
1029\table
1030\row
1031\o \snippet doc/src/snippets/declarative/qml-extending-types/signals/basic.qml 0
1032\o \snippet doc/src/snippets/declarative/qml-extending-types/signals/no-parameters.qml 0
1033\endtable
1034
1035If the signal has parameters, they are accessible by parameter name in the signal handler.
1036In the example below, \c buttonClicked is emitted with \c xPos and \c yPos parameters instead:
1037
1038\table
1039\row
1040\o \snippet doc/src/snippets/declarative/qml-extending-types/signals/Button.qml 0
1041\o \snippet doc/src/snippets/declarative/qml-extending-types/signals/parameters.qml 0
1042\endtable
1043
1044
1045\section2 Connecting signals to methods and other signals
1046
1047Signal objects have a \c connect() method that can be used to a connect a signal to a method or
1048another signal. When a signal is connected to a method, the method is automatically invoked
1049whenever the signal is emitted. (In Qt terminology, the method is a \e slot that is connected
1050to the \e signal; all methods defined in QML are created as Qt slots.) This enables a signal
1051to be received by a method instead of a \l {Signal Handlers}{signal handler}.
1052
1053For example, the \c application.qml above could be rewritten as:
1054
1055\snippet doc/src/snippets/declarative/qml-extending-types/signals/connectslots.qml 0
1056
1057The \c myMethod() method will be called whenever the \c buttonClicked signal is received.
1058
1059In many cases it is sufficient to receive signals through signal handlers rather than using
1060the \c connect() function; the above example does not provide any improvements over using a
1061simple \c onButtonClicked handler. However, if you are \l{Dynamic Object Management in QML}{creating objects dynamically},
1062or \l {Integrating JavaScript}{integrating JavaScript code}, then you will find the
1063\c connect() method useful. For example, the component below creates three \c Button
1064objects dynamically, and connects the \c buttonClicked signal of each object to the
1065\c myMethod() function:
1066
1067\snippet doc/src/snippets/declarative/qml-extending-types/signals/connectdynamic.qml 0
1068
1069In the same way, you could connect a signal to methods defined in a dynamically
1070created object, or \l {Receiving QML Signals in JavaScript}{connect a signal to a JavaScript method}.
1071
1072There is also a corresponding \c disconnect() method for removing connected signals. The following
1073code removes the connection created in \c application.qml above:
1074
1075\qml
1076// application.qml
1077Item {
1078 ...
1079
1080 function removeSignal() {
1081 button.clicked.disconnect(item.myMethod)
1082 }
1083}
1084\endqml
1085
1086
1087\section3 Forwarding signals
1088
1089The \c connect() method can also connect a signal to other signals. This has the effect
1090of "forwarding" a signal: it is automatically emitted whenever the relevant signal is emitted. For
1091example, the MouseArea \c onClicked handler in \c Button.qml above could have been replaced with
1092a call to \c connect():
1093
1094\qml
1095MouseArea {
1096 anchors.fill: parent
1097 Component.onCompleted: clicked.connect(item.buttonClicked)
1098}
1099\endqml
1100
1101Whenever the \l MouseArea \c clicked signal is emitted, the \c rect.buttonClicked signal will
1102automatically be emitted as well.
1103
1104*/
Note: See TracBrowser for help on using the repository browser.