diff options
Diffstat (limited to 'src/qml/doc/src/bindings/properties-methods-signals.qdoc')
-rw-r--r-- | src/qml/doc/src/bindings/properties-methods-signals.qdoc | 464 |
1 files changed, 464 insertions, 0 deletions
diff --git a/src/qml/doc/src/bindings/properties-methods-signals.qdoc b/src/qml/doc/src/bindings/properties-methods-signals.qdoc new file mode 100644 index 0000000000..2aa11e9a50 --- /dev/null +++ b/src/qml/doc/src/bindings/properties-methods-signals.qdoc @@ -0,0 +1,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 + + +*/ |