diff options
Diffstat (limited to 'src/qml/doc/src/cppintegration/data.qdoc')
-rw-r--r-- | src/qml/doc/src/cppintegration/data.qdoc | 843 |
1 files changed, 254 insertions, 589 deletions
diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index 7429a1d2bf..bdfb6fa235 100644 --- a/src/qml/doc/src/cppintegration/data.qdoc +++ b/src/qml/doc/src/cppintegration/data.qdoc @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ @@ -26,114 +26,144 @@ ****************************************************************************/ /*! \page qtqml-cppintegration-data.html -\title Exposing Data from C++ to QML -\brief Description of how to expose data from C++ to QML +\title Data Type Conversion Between QML and C++ +\brief Description of how data types are exchanged between QML and C++ +When data values are exchanged between QML and C++, they are converted by the +QML engine to have the correct data types as appropriate for use in QML or +C++. This requires the exchanged data to be of a type that is recognizable by +the engine. -// XXX TODO The content of "Exposing C++ Functionality To QML" and -// "Exposing Data From C++ To QML" should probably be grouped together -// on the same page, or separated in a more distinct way. -// [CA]: I'm not so sure. Functions vs Data is separate and distinct. -// I like the separation of pages, to be honest. +The QML engine provides built-in support for a large number of Qt C++ data +types. Additionally, custom C++ types may be registered with the QML type +system to make them available to the engine. +This page discusses the data types supported by the QML engine and how +they are converted between QML and C++. -\section1 Ownership Semantics -The ownership of data transferred from C++ to QML always remains with C++ in all -cases, except for one (where a QObject is returned from a method invocation). -More information about that possible ownership change is included -below. Furthermore, QML respects the normal QObject parent ownership -semantics of Qt C++, and won't ever take ownership of a QObject which -already has a parent. +\section1 Basic Qt Data Types -\section1 Context Properties - -Data from C++ may be exposed to QML via context properties. -Since all expressions evaluated in QML are evaluated in a -particular context, if the context is modified, all bindings -in that context will be re-evaluated, and thus this method -should be used with care (or only during initialization). - -\section1 Instance Property Access - -Data from a registered C++ type may be exposed as a property -which has been declared using the Q_PROPERTY macro. Such a -property will be accessible from QML code. - - - -\target properties-cpp - -Any \l {The Property System}{Qt properties} - that is, those declared with the Q_PROPERTY() -macro - are accessible from QML. Here is a modified version of the \l {Embedding C++ objects into -QML components}{earlier example} on this page; here, the \c ApplicationData class has a \c backgroundColor -property. This property can be written to and read from QML: +By default, QML recognizes the following Qt data types, which are +automatically converted to a corresponding \l {QML Basic Type}{QML basic type} +when passed from C++ to QML and vice-versa: \table -\row -\li \snippet qml/qtbinding/properties-cpp/applicationdata.h 0 -\li \snippet qml/qtbinding/properties-cpp/MyItem.qml 0 + \row + \li Qt Type + \li QML Basic Type + \row + \li bool + \li \l bool + \row + \li unsigned int, int + \li \l int + \row + \li double + \li \l double + \row + \li float, qreal + \li \l real + \row + \li QString + \li \l string + \row + \li QUrl + \li real + \row + \li QColor + \li \l color + \row + \li QFont + \li \l font + \row + \li QDate + \li \l date + \row + \li QTime, QDateTime + \li \l time + \row + \li QPoint, QPointF + \li \l point + \row + \li QSize, QSizeF + \li \l size + \row + \li QRect, QRectF + \li \l rect + \row + \li QMatrix4x4 + \li \l matrix4x4 + \row + \li QQuaternion + \li \l quaternion + \row + \li QVector2D, QVector3D, QVector4D + \li \l vector2d, \l vector3d, \l vector4d + \row + \li Enums declared with Q_ENUMS() + \li \l enumeration \endtable -Notice the \c backgroundColorChanged signal is declared as the NOTIFY signal for the -\c backgroundColor property. If a Qt property does not have an associated NOTIFY signal, -the property cannot be used for \l{Property Binding}, as the QML engine would not be -notified when the value changes. If you are using custom types in QML, make sure their -properties have NOTIFY signals so that they can be used in property bindings. +(Note that classes provided by the QtGui module, such as QColor, QFont, +QQuaternion and QMatrix4x4, are only available from QML when the \l QtQuick +module is imported.) -See \l {Tutorial: Extending QML with C++} for further details and examples -on using Qt properties with QML. +As a convenience, many of these types can be specified in QML by string values, +or by a related method provided by the \l {QML:Qt} object. For example, the \l +{Image::sourceSize} property is of type \l size (which automatically translates +to the QSize type) and can be specified by a string value formatted as +"width\c{x}height", or by the Qt.size() function: +\qml +Item { + Image { sourceSize: "100x200" } + Image { sourceSize: Qt.size(100, 200) } +} +\endqml +See documentation for each individual type under \l {QML Basic Types} for more +information. -\section1 Supported Data Types +\section1 QObject-derived Types -Any C++ data that is used from QML - whether as custom properties, or parameters for signals or -functions - must be of a type that is recognizable by QML. +Any QObject-derived class may be used as a type for the exchange of data between +QML and C++, providing the class has been registered with the QML type system. -By default, QML recognizes the following data types: +The engine allows the registration of both instantiable and non-instantiable +types. Once a class is registered as a QML type, it can be used as a data type +for exchanging data between QML and C++. See +\l{qtqml-cppintegration-definetypes.html#registering-c++-types-with-the-qml-type-system}{Registering C++ types with the QML type system} for further details on type registration. -// XXX TODO This list should refer to "QML Basic Types" list to refer to the type conversions -\list -\li bool -\li unsigned int, int -\li float, double, qreal -\li QString -\li QUrl -\li QColor -\li QDate, QTime, QDateTime -\li QPoint, QPointF -\li QSize, QSizeF -\li QRect, QRectF -\li QVariant -\li QVariantList, QVariantMap -\li QObject* -\li Enumerations declared with Q_ENUMS() -\endlist - -To allow a custom C++ type to be created or used in QML, the C++ class must be registered as a QML -type using qmlRegisterType(), as shown in the \l {Defining new QML elements} section above. +\section1 Conversion Between Qt and JavaScript Types +The QML engine has built-in support for converting a number of Qt types to +related JavaScript types, and vice-versa, when transferring data between QML +and C++. This makes it possible to use these types and receive them in C++ or +JavaScript without needing to implement custom types that provide access to +the data values and their attributes. +(Note that the JavaScript environment in QML modifies native JavaScript object +prototypes, including those of \c String, \c Date and \c Number, to provide +additional features. See the \l {qtqml-javascript-hostenvironment.html} +{JavaScript Host Environment} for further details.) -\section2 JavaScript Arrays and Objects +\section2 QVariantList and QVariantMap to JavaScript Array and Object -There is built-in support for automatic type conversion between QVariantList and JavaScript -arrays, and QVariantMap and JavaScript objects. +The QML engine provides automatic type conversion between QVariantList and +JavaScript arrays, and between QVariantMap and JavaScript objects. -For example, the function defined in QML below left expects two arguments, an array and an object, and prints -their contents using the standard JavaScript syntax for array and object item access. The C++ code -below right calls this function, passing a QVariantList and a QVariantMap, which are automatically +For example, the function defined in QML below left expects two arguments, an +array and an object, and prints their contents using the standard JavaScript +syntax for array and object item access. The C++ code below right calls this +function, passing a QVariantList and a QVariantMap, which are automatically converted to JavaScript array and object values, repectively: \table \header -\li Type -\li String format -\li Example \row \li \snippet qml/qtbinding/variantlistmap/MyItem.qml 0 \li \snippet qml/qtbinding/variantlistmap/main.cpp 0 @@ -149,553 +179,188 @@ Object item: language = QML Object item: released = Tue Sep 21 2010 00:00:00 GMT+1000 (EST) \endcode -Similarly, if a C++ type uses a QVariantList or QVariantMap type for a property or method -parameter, the value can be created as a JavaScript array or object in the QML -side, and is automatically converted to a QVariantList or QVariantMap when it is passed to C++. - - -\section2 Using Enumerations of a Custom Type - -To use an enumeration from a custom C++ component, the enumeration must be declared with Q_ENUMS() to -register it with Qt's meta object system. For example, the following C++ type has a \c Status enum: - -\snippet qml/qtbinding/enums/imageviewer.h start -\snippet qml/qtbinding/enums/imageviewer.h end - -Providing the \c ImageViewer class has been registered using qmlRegisterType(), its \c Status enum can -now be used from QML: - -\snippet qml/qtbinding/enums/standalone.qml 0 +Similarly, if a C++ type uses a QVariantList or QVariantMap type for a property +type or method parameter, the value can be created as a JavaScript array or +object in QML, and is automatically converted to a QVariantList or QVariantMap +when it is passed to C++. -The C++ type must be registered with QML to use its enums. If your C++ type is not instantiable, it -can be registered using qmlRegisterUncreatableType(). To be accessible from QML, the names of enum values -must begin with a capital letter. -See the \l {Tutorial: Extending QML with C++}{Writing QML extensions with C++} tutorial and -the \l{Extending QML with C++} reference documentation for -more information. +\section2 QDateTime to JavaScript Date +The QML engine provides automatic type conversion between QDateTime values and +JavaScript \c Date objects. -\section2 Using Enumeration Values as Signal and Method Parameters - -C++ signals may pass enumeration values as signal parameters to QML, providing that the enumeration -and the signal are declared within the same class, or that the enumeration value is one of those declared -in the \l {Qt}{Qt Namespace}. - -Likewise, invokable C++ method parameters may be enumeration values providing -that the enumeration and the method are declared within the same class, or that -the enumeration value is one of those declared in the \l {Qt}{Qt Namespace}. - -Additionally, if a C++ signal with an enum parameter should be connectable to a QML function using the -\l{QML Signal and Handler Event System#Connecting Signals to Methods and Signals}{connect()} -function, the enum type must be registered using qRegisterMetaType(). - -For QML signals, enum values may be used as signal parameters using the \c int type: - -\snippet qml/qtbinding/enums/standalone.qml 1 - - - - -\section2 Automatic Type Conversion from Strings - -As a convenience, some basic types can be specified in QML using format strings to make it easier to -pass simple values from QML to C++. +For example, the function defined in QML below left expects a JavaScript +\c Date object, and also returns a new \c Date object with the current date and +time. The C++ code below right calls this function, passing a QDateTime value +that is automatically converted by the engine into a \c Date object when it is +passed to the \c readDate() function. In turn, the readDate() function returns +a \c Date object that is automatically converted into a QDateTime value when it +is received in C++: \table \header -\li Type -\li String format -\li Example -\row -\li QColor -\li Color name, "#RRGGBB", "#RRGGBBAA" -\li "red", "#ff0000", "#ff000000" -\row -\li QDate -\li "YYYY-MM-DD" -\li "2010-05-31" -\row -\li QPoint -\li "x,y" -\li "10,20" -\row -\li QRect -\li "x,y,WidthxHeight" -\li "50,50,100x100" -\row -\li QSize -\li "WidthxHeight" -\li "100x200" \row -\li QTime -\li "hh:mm:ss" -\li "14:22:55" -\row -\li QUrl -\li URL string -\li "http://www.example.com" -\row -\li QVector3D -\li "x,y,z" -\li "0,1,0" -\row -\li Enumeration value -\li Enum value name -\li "AlignRight" -\endtable - -(More details on these string formats and types can be found in the -\l {QML Basic Types}{basic type documentation}.) - -These string formats can be used to set QML \c property values and pass arguments to C++ -functions. This is demonstrated by various examples on this page; in the above -\l{#properties-cpp}{Qt properties example}, the \c ApplicationData class has a \c backgroundColor -property of a QColor type, which is set from the QML code with the string "red" rather rather -than an actual QColor object. - -If it is preferred to pass an explicitly-typed value rather than a string, the global -\l{QmlGlobalQtObject}{Qt object} provides convenience functions for creating some of the object -types listed above. For example, \l{QML:Qt::rgba()}{Qt.rgba()} creates a QColor value from four -RGBA values. The QColor returned from this function could be used instead of a string to set -a QColor-type property or to call a C++ function that requires a QColor parameter. - - - - -\section1 Data Returned from Instance Method Invocation - -A registered C++ type may have functions flagged with the -Q_INVOKABLE flag defined. Those functions of an instance of -such a type will be accessible from QML. The function may -have a return value, which will be converted to a JavaScript -value when accessed from a JavaScript expression in QML. - -Note that if the return value is a QObject pointer (or a -pointer to a QObject-derived type), the QML engine will assume -ownership of it unless the object has had its ownership previously -explicitly set (to QQmlEngine::CppOwnership). +\li +\qml +// MyItem.qml +Item { + function readDate(dt) { + console.log("The given date is:", dt.toUTCString()); + return new Date(); + } +} +\endqml +\li +\code +// C++ +QQuickView view(QUrl::fromLocalFile("MyItem.qml")); +QDateTime dateTime = QDateTime::currentDateTime(); +QDateTime retValue; +QMetaObject::invokeMethod(view.rootObject(), "readDate", + Q_RETURN_ARG(QVariant, retValue), + Q_ARG(QVariant, QVariant::fromValue(dateTime))); -\section2 Embedding C++ Objects into QML Components +qDebug() << "Value returned from readDate():" << retValue; +\endcode -When loading a QML scene into a C++ application, it can be useful to directly embed C++ data into -the QML object. QQmlContext enables this by exposing data to the context of a QML -component, allowing data to be injected from C++ into QML. +\endtable -For example, here is a QML item that refers to a \c currentDateTime value that does not exist in -the current scope: +Similarly, if a C++ type uses a QDateTime for a property type or method +parameter, the value can be created as a JavaScript \c Date object in QML, and +is automatically converted to a QDateTime value when it is passed to C++. -\snippet qml/qtbinding/context/MyItem.qml 0 -This \c currentDateTime value can be set directly by the C++ application that loads the QML -component, using QQmlContext::setContextProperty(): +\section2 Sequence Type to JavaScript Array -\snippet qml/qtbinding/context/main.cpp 0 +Certain C++ sequence types are supported transparently in QML as JavaScript +\c Array types. -Context properties can hold either QVariant or QObject* values. This means custom C++ objects can -also be injected using this approach, and these objects can be modified and read directly in QML. -Here, we modify the above example to embed a QObject instance instead of a QDateTime value, and the QML code -invokes a method on the object instance: +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 -\snippet qml/qtbinding/context-advanced/applicationdata.h 0 -\codeline -\snippet qml/qtbinding/context-advanced/main.cpp 0 -\li -\snippet qml/qtbinding/context-advanced/MyItem.qml 0 +\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 -(Note that date/time values returned from C++ to QML can be formatted through -\l{QML:Qt::formatDateTime}{Qt.formatDateTime()} and associated functions.) - -If the QML item needs to receive signals from the context property, it can connect to them using the -\l Connections element. For example, if \c ApplicationData has a signal named \c -dataChanged(), this signal can be connected to using an \c onDataChanged handler within -a \l Connections object: - -\snippet qml/qtbinding/context-advanced/connections.qml 0 - -Context properties can be useful for using C++ based data models in a QML view. See the -\l {quick/modelviews/stringlistmodel}{String ListModel}, -\l {quick/modelviews/objectlistmodel}{Object ListModel} and -\l {quick/modelviews/abstractitemmodel}{AbstractItemModel} models for -respective examples on using QStringListModel, QObjectList-based models and QAbstractItemModel -in QML views. - -Also see the QQmlContext documentation for more information. - - - - +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)"). -\section1 Exposing Qt C++ Properties +\section1 Enumeration Types - The \l{QQmlEngine}{QML engine} utilizes Qt's - \l{The Property System}{Property System} and in effect, QML - \l{Property Binding}{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 {Creating QML Object Types from C++}{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. +To use a custom enumeration as a data type, its class must be registered and +the enumeration must also be declared with Q_ENUMS() to register it with Qt's +meta object system. For example, the \c Message class below has a \c Status +enum: \code -Q_PROPERTY(int size READ size WRITE setSize NOTIFY shoeChanged) + class Message : public QObject + { + Q_OBJECT + Q_ENUMS(Status) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + public: + enum Status { + Ready, + Loading, + Error + }; + Status status() const; + signals: + void statusChanged(); + }; \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 Properties} 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/qml/cppextensions/referenceexamples/grouped/example.qml ungrouped - - Alternatively, the group can be accessed as a set. - \snippet examples/qml/cppextensions/referenceexamples/grouped/example.qml grouped +Providing the \c Message class has been +\l{qtqml-cppintegration-definetypes.html#registering-c++-types-with-the-qml-type-system}{registered} with the QML type system, its \c Status enum can be used from QML: - A grouped property block is implemented as a read-only object property. The - \c shoe property shown is declared like this: +\qml +Message { + onStatusChanged: { + if (status == Message.Ready) + console.log("Message is loaded!") + } + } +\endqml - \snippet examples/qml/cppextensions/referenceexamples/grouped/person.h 1 +\note The names of enum values must begin with a capital letter in order to +be accessible from QML. - 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. +\section2 Enumeration Types as Signal and Method Parameters - \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/qml/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/qml/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/qml/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/qml/cppextensions/referenceexamples/attached/example.qml begin - \snippet examples/qml/cppextensions/referenceexamples/attached/example.qml rsvp - \snippet examples/qml/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/qml/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/qml/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/qml/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/qml/cppextensions/referenceexamples/properties/birthdayparty.h 2 - - As with the other property types, the type of list content, \a T, must be - \l{Creating QML Object Types from C++}{registered} into the runtime. - - \snippet examples/qml/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)"). - - - - -\section1 Property Value Sources - -\snippet examples/qml/cppextensions/referenceexamples/valuesource/example.qml 0 -\snippet examples/qml/cppextensions/referenceexamples/valuesource/example.qml 1 - -The QML snippet shown above applies a property value source to the \c announcement property. -A property value source generates a value for a property that changes over time. +C++ signals and methods with enumeration-type parameters can be used from QML +provided that the enumeration and the signal or method are both declared +within the same class, or that the enumeration value is one of those declared +in the \l {Qt}{Qt Namespace}. -Property value sources are most commonly used to do animation. Rather than -constructing an animation object and manually setting the animation's "target" -property, a property value source can be assigned directly to a property of any -type and automatically set up this association. +Additionally, if a C++ signal with an enum parameter should be connectable to a +QML function using the \l{QML Signal and Handler Event System#Connecting Signals +to Methods and Signals}{connect()} function, the enum type must be registered +using qRegisterMetaType(). -The example shown here is rather contrived: the \c announcement property of the -\c BirthdayParty object is a string that is printed every time it is assigned and -the \c HappyBirthdaySong value source generates the lyrics of the song -"Happy Birthday". - -\snippet examples/qml/cppextensions/referenceexamples/valuesource/birthdayparty.h 0 - -Normally, assigning an object to a string property would not be allowed. In -the case of a property value source, rather than assigning the object instance -itself, the QML engine sets up an association between the value source and -the property. - -Property value sources are special types that derive from the -QQmlPropertyValueSource base class. This base class contains a single method, -QQmlPropertyValueSource::setTarget(), that the QML engine invokes when -associating the property value source with a property. The relevant part of -the \c HappyBirthdaySong type declaration looks like this: - -\snippet examples/qml/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 0 -\snippet examples/qml/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 1 -\snippet examples/qml/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 2 - -In all other respects, property value sources are regular QML types. They must -be registered with the QML engine using the same macros as other types, and can -contain properties, signals and methods just like other types. - -When a property value source object is assigned to a property, QML first tries -to assign it normally, as though it were a regular QML type. Only if this -assignment fails does the engine call the \l {QQmlPropertyValueSource::}{setTarget()} method. This allows -the type to also be used in contexts other than just as a value source. - -\l {Extending QML - Property Value Source Example} shows the complete code used -to implement the \c HappyBirthdaySong property value source. +For QML signals, enum values may be passed as signal parameters using the \c int +type: +\qml + Message { + signal someOtherSignal(int statusValue) + Component.onCompleted: { + someOtherSignal(Message.Loading) + } + } +\endqml */ |