From 28def0bdd084989c17a157e0c4ab80c259081caa Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 23 Jul 2012 17:45:40 +1000 Subject: [PATCH] Revise the restructured "Integrating QML and C++" docs These docs were yet to be cleaned up following the recent doc restructure. This changes most of the the content in these sections and includes some new docs and examples. Currently all the code snippets are included inline. In a later patch, these should be moved into the snippets/ directories and be included using the \snippet command instead. Alternatively they can be moved into examples/ to replace the BirthdayParty examples which are no longer referenced in these docs as of this patch. Task-number: QTBUG-26381 Change-Id: I94e3654e61476fad11fe81042d1bbe94fc649d06 Reviewed-by: Chris Adams --- .../doc/src/cppintegration/contextproperties.qdoc | 95 +++ src/qml/doc/src/cppintegration/data.qdoc | 843 +++++++-------------- src/qml/doc/src/cppintegration/definetypes.qdoc | 658 ++++++++++++++++ .../src/cppintegration/exposecppattributes.qdoc | 506 +++++++++++++ src/qml/doc/src/cppintegration/functions.qdoc | 211 ------ .../doc/src/cppintegration/interactqmlfromcpp.qdoc | 259 +++++++ .../doc/src/cppintegration/registercpptypes.qdoc | 534 ------------- src/qml/doc/src/cppintegration/reverse.qdoc | 252 ------ src/qml/doc/src/cppintegration/topic.qdoc | 149 ++-- src/qml/doc/src/qtqml.qdoc | 13 +- src/qml/doc/src/typesystem/objecttypes.qdoc | 4 +- 11 files changed, 1874 insertions(+), 1650 deletions(-) create mode 100644 src/qml/doc/src/cppintegration/contextproperties.qdoc create mode 100644 src/qml/doc/src/cppintegration/definetypes.qdoc create mode 100644 src/qml/doc/src/cppintegration/exposecppattributes.qdoc delete mode 100644 src/qml/doc/src/cppintegration/functions.qdoc create mode 100644 src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc delete mode 100644 src/qml/doc/src/cppintegration/registercpptypes.qdoc delete mode 100644 src/qml/doc/src/cppintegration/reverse.qdoc diff --git a/src/qml/doc/src/cppintegration/contextproperties.qdoc b/src/qml/doc/src/cppintegration/contextproperties.qdoc new file mode 100644 index 0000000..4a35019 --- /dev/null +++ b/src/qml/doc/src/cppintegration/contextproperties.qdoc @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** 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 qtqml-cppintegration-contextproperties.html +\title Embedding C++ Objects into QML with Context Properties +\brief Description of how to embed C++ data into QML using context properties + +When loading a QML object into a C++ application, it can be useful to directly embed some C++ data +that can be used from within th QML code. This makes it possible, for example, to invoke a C++ +method on the embedded object, or use a C++ object instance as a data model for a QML view. + +The ability to inject C++ data into a QML object is made possible by the QQmlContext class. This +class exposes data to the context of a QML object so that the data can be referred to directly from +within the scope of the QML code. + + +\section1 Setting a Simple Context Property + +For example, here is a QML item that refers to a \c currentDateTime value that does not exist in +the current scope: + +\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(): + +\snippet qml/qtbinding/context/main.cpp 0 + +\note 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. Thus, context properties should be +used with care outside of application initialization, as this may lead to decreased application +performance. + + +\section1 Setting an Object as a Context Property + +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: + +\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 +\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. + +*/ diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index 7429a1d..bdfb6fa 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} + \li \c {QList} + \li \c {QList} + \li \c {QList} and \c{QStringList} + \li \c {QList} +\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 \li integer value 0 +\row \li QList \li real value 0.0 +\row \li QList \li boolean value \c {false} +\row \li QList and QStringList \li empty QString +\row \li QList \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 - onChanged, regardless of the name used for the NOTIFY - signal in C++. We recommend using 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 - . 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 - QObject *qmlAttachedPropertiesObject(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 - 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}. - - \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} - 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} - \li \c {QList} - \li \c {QList} - \li \c {QList} and \c{QStringList} - \li \c {QList} - \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 \li integer value 0 - \row \li QList \li real value 0.0 - \row \li QList \li boolean value \c {false} - \row \li QList and QStringList \li empty QString - \row \li QList \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 */ diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc new file mode 100644 index 0000000..c9750de --- /dev/null +++ b/src/qml/doc/src/cppintegration/definetypes.qdoc @@ -0,0 +1,658 @@ +/**************************************************************************** +** +** 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 qtqml-cppintegration-definetypes.html +\title Defining QML Types from C++ +\brief Description of ways to define QML object types from C++ code + +When extending QML with C++ code, a C++ class can be registered with the QML +type system to enable the class to be used as a data type within QML code. +While the properties, methods and signals of any QObject-derived class are +accessible from QML, as discussed in \l{qtqml-cppintegration-exposecppattributes.html} +{Exposing Attributes of C++ Types to QML}, such a class cannot be used as a +data type from QML until it is registered with the type system. Additionally +registration can provide other features, such as allowing a class to be used +as an instantiable \l{qtqml-typesystem-objecttypes.html}{QML object type} from +QML, or enabling a singleton instance of the class to be imported and used +from QML. + +Additionally, the QtQml module provides mechanisms for implementing QML-specific +features such as \e{attached properties} and \e{default properties} in C++. + + +\section1 Registering C++ types with the QML type system + +A QObject-derived class can be registered with the QML type system to enable the +type to be used as a data type from within QML code. + +The engine allows the registration of both instantiable and non-instantiable +types. Registering an instantiable type enables a C++ class to be used as the +definition of a QML object type, allowing it to be used in object declarations +from QML code to create objects of this type. Registration also provides +the engine with additional type metadata, enabling the type (and any enums +declared by the class) to be used as a data type for property values, method +parameters and return values, and signal parameters that are exchanged between +QML and C++. + +Registering a non-instantiable type also registers the class as a data type in +this manner, but the type cannot be used instantiated as a QML object type +from QML. This is useful, for example, if a type has enums that should be +exposed to QML but the type itself should not be instantiable. + + +\section2 Registering an Instantiable Object Type + +\bold{Any QObject-derived C++ class can be registered as the definition of a +\l{qtqml-typesystem-objecttypes.html}{QML object type}}. Once a +class is registered with the QML type system, the class can be declared and +instantiated like any other object type from QML code. Once created, a +class instance can be manipulated from QML; as +\l{qtqml-cppintegration-exposecppattributes.html}{Exposing Attributes of C++ +Types to QML} explains, the properties, methods and signals of any +QObject-derived class are accessible from QML code. + +To register a QObject-derived class as an instantiable QML object type, call the +qmlRegisterType() function with the appropriate class and module URI. + +For example, suppose there is a \c Message class with \c author and +\c creationDate properties: + +\code +class Message : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged) + Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged) +public: + // ... +}; +\endcode + +This type can be registered by calling qmlRegisterType() with an appropriate +module URI and version number. For example, to make the type available in a +module \c com.mycompany.messaging with version 1.0: + +\code +qmlRegisterType("com.mycompany.messaging", 1, 0, "Message"); +\endcode + +The type can be used in an \l{qtqml-syntax-basics.html#object-declarations}{object declaration} +from QML, and its properties can be read and written to, as per the example +below: + +\qml +import com.mycompany.messaging 1.0 + +Message { + author: "Amelie" + creationDate: new Date() +} +\endqml + + +\section2 Registering Non-Instantiable Types + +Sometimes a QObject-derived class may need to be registered with the QML type +system but not as an instantiable type. For example, this is the case if a C++ +class: + +\list +\li is an interface type that should not be instantiable +\li is a base class type that does not need to be exposed to QML +\li declares some enum that should be accessible from QML, but otherwise should +not be instantiable +\li is a type that should be provided to QML through a singleton instance, and +should not be instantiable from QML +\endlist + +The QtQml module provides several methods for registering non-instantiable +types: + +\list +\li qmlRegisterType() (with no parameters) registers a C++ type that is not +instantiable and cannot be referred to from QML. This enables the engine to +coerce any inherited types that are instantiable from QML. +\li qmlRegisterInterface() registers a Qt interface type with a specific QML +type name. The type is not instantiable from QML but can be referred to by its +type name. +\li qmlRegisterUncreatableType() registers a named C++ type that is not +instantiable but should be identifiable as a type to the QML type system. This +is useful if a type's enums or attached properties should be accessible from QML +but the type itself should not be instantiable. +\li qmlRegisterModuleApi() registers a singleton instance that can be imported +from QML, as discussed below. +\endlist + +Note that all C++ types registered with the QML type system must be +QObject-derived, even if they are non-instantiable. + + +\section3 Registering Singleton Objects with a Module API + +A Module API enables properties, signals and methods to be exposed in +a namespace without requiring the client to manually instantiate an +object instance. QObject module APIs in particular are an efficient and +convenient way to provide functionality or global property values. + +Note that module APIs do not have an associated QQmlContext as they are +shared across all contexts in an engine. QObject module API instances +are constructed and owned by the QQmlEngine, and will be destroyed when +the engine is destroyed. + +A QObject module API can be interacted with in a manner simlar to any +other QObject or instantiated element. That is, Q_PROPERTYs of QObject +module APIs may be bound to, and Q_INVOKABLE functions of QObject module +APIs may be used in signal handler expressions. This makes module APIs +an ideal way to implement styling or theming, and they can also be used +instead of ".pragma library" script imports to store global state or to +provide global functionality. + +Once registered, a QObject module API may be imported and used like any +other QObject instance exposed to QML. The following example assumes that +a QObject module API was registered into the "MyThemeModule" namespace +with version 1.0, where that QObject has a QColor "color" Q_PROPERTY: + +\qml +import MyThemeModule 1.0 as Theme + +Rectangle { + color: Theme.color // binding. +} +\endqml + +A QJSValue may also be exposed as a module API, however clients should +be aware that properties of such a module API cannot be bound to. + +See \l{qmlRegisterModuleApi()} for more information on how implement and +register a new module API, and how to use an existing module API. + + +\section2 Type Revisions and Versions + +Many of the type registration functions require versions to be specified +for the registered type. Type revisions and versions allow new properties +or methods to exist in the new version while remaining compatible with +previous versions. + +Consider these two QML files: +\code +// main.qml +import QtQuick 1.0 + +Item { + id: root + MyType {} +} +\endcode + +\code +// MyType.qml +import MyModule 1.0 + +CppType { + value: root.x +} +\endcode + +where \c CppType maps to the C++ class \c CppType. + +If the author of CppType adds a \c root property to CppType in a new +version of the module, \c root.x now resolves to a different value because +\c root is also the \c id of the top level component. The author could +specify that the new \c root property is available from a specific minor +version. This permits new properties and features to be added to existing +elements without breaking existing programs. + +The REVISION tag is used to mark the \c root property as added in revision 1 +of the class. Methods such as Q_INVOKABLE's, signals and slots can also be +tagged for a revision using the \c Q_REVISION(x) macro: + +\code +class CppType : public BaseType +{ + Q_OBJECT + Q_PROPERTY(int root READ root WRITE setRoot NOTIFY rootChanged REVISION 1) + +signals: + Q_REVISION(1) void rootChanged(); +}; +\endcode + +To register the new class revision to a particular version the following +function is used: + +\code +template +int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) +\endcode + +To register \c CppType version 1 for \c {MyModule 1.1}: + +\code +qmlRegisterType("MyModule", 1, 1, "CppType") +\endcode + +\c root is only available when MyModule 1.1 is imported. + +For the same reason, new elements introduced in later versions should use +the minor version argument of qmlRegisterType. + +This feature of the language allows for behavioural changes to be made +without breaking existing applications. Consequently QML module authors +should always remember to document what changed between minor versions, and +QML module users should check that their application still runs correctly +before deploying an updated import statement. + +You may also register the revision of a base class that your module depends upon +using the qmlRegisterRevision() function: + +\code +template +int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) + +template +int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) +\endcode + +For example, if \c BaseType is changed and now has a revision 1, you can +specify that your module uses the new revision: + +\code +qmlRegisterRevision("MyModule", 1, 1); +\endcode + +This is useful when deriving from base classes not declared as part of your +module, e.g. when extending classes from the QtQuick library. + + +\section1 Defining QML-Specific Types and Attributes + + +\section2 Providing Attached Objects for Data Annotations + +In the QML language syntax, there is a notion of \l{Attached properties and +attached signal handlers}{\e {attached properties} and \e {attached signal +handlers}}, which are additional attributes that are attached to an object. +Essentially, such attributes are implemented and provided by an \e {attaching +type}, and these attributes may be \e attached to an object of another type. +This contrasts with ordinary object properties which are provided by the object +type itself (or the object's inherited type). + +For example, the \l Item below uses attached properties and attached handlers: + +\qml +import QtQuick 2.0 + +Item { + width: 100; height: 100 + + focus: true + Keys.enabled: false + Keys.onReturnPressed: console.log("Return key was pressed") +} +\endqml + +Here, the \l Item object is able to access and set the values of \c Keys.enabled +and \c Keys.onReturnPressed. This allows the \l Item object to access these +extra attributes as an extension to its own existing attributes. + +\section3 Steps for Implementing Attached Objects + +When considering the above example, there are several parties involved: + +\list +\li There is an instance of an anonymous \e {attached object type}, with +an \c enabled and a \c returnPressed signal, that has been attached to the +\l Item object to enable it to access and set these attributes. +\li The \l Item object is the \e {attachee}, to which the instance of the \e +{attached object type} has been attached. +\li \l Keys is the \e {attaching type}, which provides the \e {attachee} with a +named qualifier, "Keys", through which it may access the attributes of the +\e {attached object type}. +\endlist + +When the QML engine processes this code, it creates a single instance of the +\e {attached object type} and attaches this instance to the \l Item object, +thereby providing it with access to the \c enabled and \c returnPressed +attributes of the instance. + +The mechanisms for providing attached objects can be implemented from C++ by +providing classes for the \e {attached object type} and \e {attaching type}. +For the \e{attached object type}, provide a QObject-derived class that defines +the attributes to be made accessible to \e attachee objects. For the +\e {attaching type}, provide a QObject-derived class that: + +\list +\li implements a static qmlAttachedProperties() with the following signature: + \code + static *qmlAttachedProperties(QObject *object); + \endcode + + This method should return an instance of the \e{attached object type}. + + The QML engine invokes this method in order to attach an instance of + the attached object type to the \e attachee specified by the \c object + paramter. It is customary, though not strictly required, for this method + implementation to parent the returned instance to \c object in order + to prevent memory leaks. + + This method is called at most once by the engine for each attachee object + instance, as the engine caches the returned instance pointer for subsequent + attached property accesses. Consequently the attachment object may not be + deleted until the attachee \c object is destroyed. + +\li is declared as an attaching type, by calling the QML_DECLARE_TYPEINFO() + macro with the QML_HAS_ATTACHED_PROPERTIES flag +\endlist + + +\section3 Implementing Attached Objects: An Example + +For example, take the \c Message type described in an \l{Registering an +Instantiable Object Type}{earlier example}: + +\code +class Message : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged) + Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged) +public: + // ... +}; +\endcode + +Suppose it is necessary to trigger a signal on a \c Message when it is +published to a message board, and also track when the message has expired on +the message board. Since it doesn't make sense to add these attributes +directly to a \c Message, as the attributes are more relevant to the message +board context, they could be implemented as \e attached attributes on a +\c Message object that are provided through a "MessageBoard" qualifier. In +terms of the concepts described earlier, the parties involved here are: + +\list +\li An instance of an anonymous \l{attached object type}, which provides a + \c published signal and an expired property. This type is implemented by + \c MessageBoardAttachedType below +\li A \c Message object, which will be the \e attachee +\li The \c MessageBoard type, which will be the \e {attaching type} that is + used by \c Message objects to access the attached attributes +\endlist + +Following is an example implementation. First, there needs to be an +\e {attached object type} with the necessary properties and signals that +will be accessible to the \e attachee: + +\code +class MessageBoardAttachedType : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool expired READ expired WRITE expired NOTIFY expiredChanged) +public: + MessageBoardAttachedType(QObject *parent); + bool expired() const; + void setExpired(bool expired); +signals: + void published(); + void expiredChanged(); +}; +\endcode + +Then the \e {attaching type}, \c MessageBoard, must declare a \c +qmlAttachedProperties() method that returns an instance of the +\e {attached object type} as implemented by MessageBoardAttachedType. +Additionally, \c Message board must be declared as an attached type +through the QML_DECLARE_TYPEINFO() macro: + +\code +class MessageBoard : public QObject +{ + Q_OBJECT +public: + static MessageBoard *qmlAttachedProperties(QObject *object) + { + return new MessageBoardAttachedType(object); + } +}; +QML_DECLARE_TYPEINFO(MessageBoard, QML_HAS_ATTACHED_PROPERTIES) +\endcode + +Now, a \c Message type can access the properties and signals of the attached +object type: + +\qml +Message { + author: "Amelie" + creationDate: new Date() + + MessageBoard.expired: creationDate < new Date("January 01, 2015 10:45:00") + MessageBoard.onPublished: console.log("Message by", author, "has been +published!") +} +\endqml + +Additionally, the C++ implementation may access the attached object instance +that has been attached to any object by calling the +qmlAttachedPropertiesObject() function. + + +\section2 Property Value Sources + +In the QML language syntax, there is a concept of \e {property value sources}. +These are QML types that can automatically update the value of a property over +time, using the \c { on } syntax. For example, +the various \l{qtquick-statesanimations-animations.html}{property animation} +types provided by the \c QtQuick module are examples of property value sources. + +A property value source can be implemented in C++ by subclassing +QQmlPropertyValueSource and providing an implementation that writes different +values to a property over time. When the property value source is applied to a +property using the \c { on } syntax in QML, it +is given a reference to this property by the engine so that the property value +can be updated. + +For example, suppose there is a \c RandomNumberGenerator class to be made +available as a property value source, so that when applied to a QML property, +it will update the property value to a different random number every 500 +milliseconds. Additionally, a maxValue can be provided to this random number +generator. This class can be implemented as follows: + +\code +class RandomNumberGenerator : public QObject, public QQmlPropertyValueSource +{ + Q_OBJECT + Q_INTERFACES(QQmlPropertyValueSource) + Q_PROPERTY(int maxValue READ maxValue WRITE setMaxValue NOTIFY maxValueChanged); +public: + RandomNumberGenerator(QObject *parent) + : QObject(parent), m_maxValue(100) + { + qsrand(QDateTime::currentDateTime().toTime_t()); + QObject::connect(&m_timer, SIGNAL(timeout()), SLOT(updateProperty())); + m_timer.start(500); + } + + int maxValue() const; + void setMaxValue(int maxValue); + + virtual void setTarget(const QQmlProperty &prop) { m_targetProperty = prop; } + +signals: + void maxValueChanged(); + +private slots: + void updateProperty() { + m_targetProperty.write(qrand() % m_maxValue); + } + +private: + QQmlProperty m_targetProperty; + QTimer m_timer; + int m_maxValue; +}; +\endcode + +When the QML engine encounters a use of \c RandomNumberGenerator as a property +value source, it invokes \c RandomNumberGenerator::setTarget() to provide the +type with the property to which the value source has been applied. When the +internal timer in \c RandomNumberGenerator triggers every 500 milliseconds, +it will write a new number value to that specified property. + +Once the \c RandomNumberGenerator class has been registered with the QML type +system, it can be used from QML as a property value source. Below, it is used +to change the width of a \l Rectangle every 500 milliseconds: + +\qml +import QtQuick 2.0 + +Item { + width: 300; height: 300 + + Rectangle { + RandomNumberGenerator on width { maxValue: 300 } + + height: 100 + color: "red" + } +} +\endqml + +In all other respects, property value sources are regular QML types that can +have properties, signals methods and so on, but with the added capability that +they can be used to change property values using the +\c { on } syntax. + +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. + + +\section2 Specifying Default Properties for QML Object Types + +Any QObject-derived type that is registered as an instantiable QML object type +can optionally specify a \e {default property} for the type. A default +property is the property to which an object's children are automatically +assigned if they are not assigned to any specific property. + +The default property can be set by calling the Q_CLASSINFO() macro for a class +with a specific "DefaultProperty" value. For example, the \c MessageBoard +class below specifies its \c messages property as the default property for the +class: + +\code +class MessageBoard : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty messages READ messages) + Q_CLASSINFO("DefaultProperty", "messages") +public: + QQmlListProperty messages() const; + +private: + QList messages; +}; +\endcode + +This enables children of a \c MessageBoard object to be automatically assigned +to its \c messages property if they are not assigned to a specific property. For +example: + +\qml +MessageBoard { + Message { author: "Naomi" } + Message { author: "Clancy" } +} +\endqml + +If \c messages was not set as the default property, then any \c Message objects +would have to be explicitly assigned to the \c messages property instead, as +follows: + +\qml +MessageBoard { + messages: [ + Message { author: "Naomi" }, + Message { author: "Clancy" } + ] +} +\endqml + +(Incidentally, the \l Item::children property is its default property, which +enables visual children to be conveniently declared for any \l Item-based +type without explicitly assigning them to this 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 default +property can refer to a property declared in the class itself, or a property +inherited from a base class. + + +\section2 Defining Visual Items with the QtQuick Module + +When building user interfaces with the QtQuick module, all QML objects that are +to be visually rendered must derive from the \l Item type, as it is the base +type for all visual objects in the QtQuick module. This \l Item type is +implemented by the QQuickItem C++ class, which is provided as part of the +QtQuick C++ module. Therefore, this class should be subclassed when it is +necessary to implement a visual type in C++ that can be integrated into a +QML-based user interface. + +See the QQuickItem documentation for more information. + + +\section1 Receiving Notifications for Object Initialization + +For some custom QML object types, it may be beneficial to delay the +initialization of particular data until the object has been created and all of +its properties have been set. For example, this may be the case if the +initialization is costly, or if the initialization should not be performed until +all property values have been initialized. + +The QtQml module provides the QQmlParserStatus to be subclass for these +purposes. It defines a number of virtual methods that are invoked invoked at +various stages during component instantiation. To receive these notifications, a +C++ class should inherit QQmlParserStatus and also notify the Qt meta system +using the Q_INTERFACES() macro. + +For example: + +\code +class MyQmlType : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) +public: + virtual void componentComplete() + { + // Perform some initialization here now that the object is fully created + } +}; +\endcode + +*/ \ No newline at end of file diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc new file mode 100644 index 0000000..6d8718e --- /dev/null +++ b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc @@ -0,0 +1,506 @@ +/**************************************************************************** +** +** 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 qtqml-cppintegration-exposecppattributes.html +\title Exposing Attributes of C++ Types to QML +\brief Description of how to expose the attributes of a C++ type to QML + +QML can easily be extended with functionality defined in C++ code. Due to the +tight integration of the QML engine with the \l{The Meta-Object System}{Qt +meta-object system}, any functionality that is appropriately exposed by a +QObject-derived class is accessible from QML code. This enables C++ data and +functions to be accessible directly from QML, often with little or no +modification. + +The QML engine has the ability to introspect QObject instances through the +meta-object system. This means any QML code can access the following members of +an instance of a QObject-derived class: + +\list +\li Properties +\li Methods (providing they are public slots or flagged with Q_INVOKABLE) +\li Signals +\endlist + +(Additionally, enums are available if they have been declared with Q_ENUMS. +See \l{qtqml-cppintegration-data.html}{Data Type Conversion Between QML and C++} +for more details.) + +In general, these are accessible from QML regardless of whether a +QObject-derived class has been \l{Registering C++ types with the QML type +system}{registered with the QML type system}. However, if if a class is to be +used in a way that requires the engine to access additional type information +— for example, if the class itself is to be used as a method parameter or +property, or if one of its enum types is to be used in this way — then the +class may need to be registered. + + +\section1 Properties + +A \e property can be specified for any QObject-derived class using the +Q_PROPERTY() macro. A property is a class data member with an associated read +function and optional write function. + +All properties of a QObject-derived class are accessible from QML. + +For example, below is a \c Message class with an \c author property. As +specified by the Q_PROPERTY macro call, this property is readable through +the \c author() method, and writable through the \c setAuthor() method: + +\code +class Message : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged) +public: + void setAuthor(const QString &a) { + if (a != m_author) { + m_author = a; + emit authorChanged(); + } + } + QString author() const { + return m_author; + } +private: + QString m_author; +}; +\endcode + +If an instance of this class was \l{Embedding C++ Objects into QML with Context +Properties}{set as a context property} when loading a file named \c MyItem.qml +from C++: + +\code + int main(int argc, char *argv[]) { + QCoreApplication app(argc, argv); + + QQmlEngine engine; + Message msg; + engine.rootContext()->setContextProperty("msg", &msg); + QQmlComponent component(&engine, QUrl::fromLocalFile("MyItem.qml")); + component.create(); + + return app.exec(); + } +\endcode + +Then, the \c author property could be read from \c MyItem.qml: + +\qml +// MyItem.qml +import QtQuick 2.0 + +Text { + width: 100; height: 100 + text: msg.author // invokes Message::author() to get this value + + Component.onCompleted: { + msg.author = "Jonah" // invokes Message::setAuthor() + } +} +\endqml + +For maximum interopability with QML, \bold {any property that is writable should +have an associated NOTIFY signal} that is emitted whenever the property value +has changed. This allows the property to be used with \l{Property +Binding}{property binding}, which is an essential feature of QML that enables +specific values to be updated whenever an associated property changes. + +In the above example, the associated NOTIFY signal for the \c author property is +\c authorChanged, as specified in the Q_PROPERTY() macro call. This means that +whenever the signal is emitted — as it is when the author changes +in Message::setAuthor() — this notifies the QML engine that any +bindings involving the \c author property must be updated, and in turn, the +engine will update the \c text property by calling \c Message::author() again. + +If the \c author property was writable but did not have an associated NOTIFY +signal, the \c text value would be initialized with the initial value returned +by \c Message::author() but would not be updated with any later changes to this +property. In addition, any attempts to bind to the property from QML will +produce a runtime warning from the engine. + +\note It is recommended that the NOTIFY signal be named \e Changed +where \c is the name of the property. The associated property +change signal handler generated by the QML engine will always take the form +\c onChanged, regardless of the name of the related C++ signal, so +it is recommended that the signal name follows this convention to avoid any +confusion. + + +\section3 Notes on Use of Notify Signals + +To prevent loops or excessive evaluation, developers should ensure that the +property change signal is only emitted when the property value has actually +changed. Also, 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. + +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. + +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. + + +\section2 Properties with Object Types + +Object-type properties are accessible from QML providing that the object type +has been appropriately \l{Registering C++ types with the QML type +system}{registered} with the QML type system. + +For example, the \c Message type might have a \c body property of type +\c MessageBody*: + +\code +class Message : public QObject +{ + Q_OBJECT + Q_PROPERTY(MessageBody* body READ body WRITE setBody NOTIFY bodyChanged) +public: + MessageBody* body() const; + void setBody(MessageBody* body); +}; + +class MessageBody : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE text NOTIFY textChanged) +// ... +} +\endcode + +Suppose the \c Message type was \l{Registering C++ types with the QML type +system}{registered} with the QML type system, allowing it to be used as an +object type from QML code: + +\qml +Message { + // ... +} +\endqml + +If the \c MessageBody type was also registered with the type system, it would be +possible to assign \c MessageBody to the \c body property of a \c Message, all +from within QML code: + +\qml +Message { + body: MessageBody { + text: "Hello, world!" + } +} +\endqml + + +\section2 Properties with Object-List Types + +Properties containing lists of QObject-derived types can also be exposed to +QML. For this purpose, however, one should use QQmlListProperty rather than +QList as the property type. This is because QList is not a QObject-derived +type, and so cannot provide the necessary QML property characteristics +through the Qt meta object system, such as signal notifications when a list +is modified. + +QQmlListProperty is a template class that can be conveniently constructed from +a QList value. + +For example, the \c MessageBoard class below has a \c messages property of +type QQmlListProperty that stores a list of \c Message instances: + +\code +class MessageBoard : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty messages READ messages) +public: + QQmlListProperty messages() const; + +private: + static void append_message(QQmlListProperty *list, Message *msg); + + QList m_messages; +}; +\endcode + +The MessageBoard::messages() function simply creates and returns a +QQmlListProperty from its QList \c m_messages member, passing the +appropriate list modification functions as required by the QQmlListProperty +constructor: + +\code +QQmlListProperty MessageBoard::messages() +{ + return QQmlListProperty(this, 0, &MessageBoard::append_message); +} + +void MessageBoard::append_message(QQmlListProperty *list, Message *msg) +{ + MessageBoard *msgBoard = qobject_cast(list->object); + if (msg) + msgBoard->m_messages.append(msg); +} +\endcode + +Note that the template class type for the QQmlListProperty — in this case, +\c Message — must be \l{Registering C++ types with the QML type system} +{registered} with the QML type system. + + +\section2 Grouped Properties + +Any read-only object-type property is accessible from QML code as a +\e {grouped property}. This can be used to expose a group of related +properties that describe a set of attributes for a type. + +For example, suppose the \c Message::author property was of type +\c MessageAuthor rather than a simple string, with sub-properties +of \c name and \c email: + +\code +class MessageAuthor : public QObject +{ + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString email READ email WRITE setEmail) +public: + ... +}; + +class Message : public QObject +{ + Q_OBJECT + Q_PROPERTY(MessageAuthor* author READ author) +public: + Message(QObject *parent) + : QObject(parent), m_author(new MessageAuthor(this)) + { + } + Message *author() const { + return m_author; + } +private: + Message *m_author; +}; +\endcode + +The \c author property could be written to using the +\l{qtqml-syntax-objectattributes.html#grouped-properties}{grouped property +syntax} +in QML, like this: + +\qml +Message { + author.name: "Alexandra" + author.email: "alexandra@mail.com" +} +\endqml + +A type that is exposed as a grouped property differs from an \l{Properties with +Object Types}{object-type property} in that the grouped property is read-only, +and is initialized to a valid value by the parent object at construction. The +grouped property's sub-properties may be modified from QML but the grouped +property object itself will never change, whereas an object-type property may be +assigned a new object value from QML at any time. Thus, the lifetime of a +grouped property object is controlled strictly by the C++ parent +implementation, whereas an object-type property can be freely created and +destroyed through QML code. + + +\section1 Methods (including Qt Slots) + +Any method of a QObject-derived type is accessible from QML code if it is: + +\list +\li A public method flagged with the Q_INVOKABLE() macro +\li A method that is a public Qt \l{Signals & Slots}{slot} +\endlist + +For example, the \c MessageBoard class below has a \c postMessage() method that +has been flagged with the Q_INVOKABLE macro, as well as a \c refresh() method +that is a public slot: + +\code + class MessageBoard : public QObject + { + Q_OBJECT + public: + Q_INVOKABLE bool postMessage(const QString &msg) { + qDebug() << "Called the C++ method with" << msg; + return true; + } + + public slots: + void refresh() { + qDebug() << "Called the C++ slot"; + } + }; +\endcode + +If an instance of \c MessageBoard was set as the context data for a file \c +MyItem.qml, as shown below left, then \c MyItem.qml could invoke the two +methods, as shown below right: + +\table +\row +\li +\code + int main(int argc, char *argv[]) { + QCoreApplication app(argc, argv); + + QQmlEngine engine; + Message msg; + engine.rootContext()->setContextProperty("msg", &msg); + QQmlComponent component(&engine, QUrl::fromLocalFile("MyItem.qml")); + component.create(); + + return app.exec(); + } +\endcode +\li +\qml +// MyItem.qml +import QtQuick 2.0 + +Item { + width: 100; height: 100 + + MouseArea { + anchors.fill: parent + onClicked: { + var result = msgBoard.postMessage("Hello from QML") + console.log("Result of postMessage():", result) + msgBoard.refresh(); + } + } +} +\endqml +\endtable + +Note that any QML object may be passed as an argument to a Q_INVOKABLE C++ +method if that method has a QObject pointer as a parameter. The object +may be passed via its id, or via a JavaScript \l var that references the +object. + +QML supports the calling of overloaded C++ functions. If there are multiple C++ +functions with the same name but different arguments, the correct function will +be called according to the number and the types of arguments that are provided. + +Values returned from C++ methods are converted to JavaScript values when +accessed from JavaScript expressions in QML. + + +\section1 Signals + +Any public \l{Signals & Slots}{signal} of a QObject-derived type is accessible +from QML code. + +The QML engine automatically creates a \l{Signal and Handler Event +System}{signal handler} for any signal of a QObject-derived type that is used +from QML. Signal handlers are always named \e on where \c is +the name of the signal, with the first letter capitalized. All parameters passed +by the signal are available in the signal handler through the parameter names. + +For example, suppose the \c MessageBoard class has a \c newMessagePosted() +signal with a single parameter, \c subject: + +\code + class MessageBoard : public QObject + { + Q_OBJECT + public: + // ... + signals: + void newMessagePosted(const QString &subject); + }; +\endcode + +If the \c MessageBoard type was \l{Registering C++ types with the QML type +system}{registered} with the QML type system, then a \c MessageBoard object +declared in QML could receive the \c newMessagePosted() signal using a signal +handler named \c onNewMessagePosted, and examine the \c subject parameter +value: + +\qml +MessageBoard { + onNewMessagePosted: console.log("New message received:", subject) +} +\endqml + +As with property values and method parameters, a signal parameter must have a +type that is supported by the QML engine; see +\l {Semantics of Data Transfer from C++ to QML}. (Using an +unregistered type will not generate an error, but the parameter value will +not be accessible from the handler.) + +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. + + +\section1 Semantics of Data Transfer from C++ to QML + +There are several issues to be aware of when transferring data from C++ to +QML, including how data types are processed by the engine, and where +ownership of the transferred data lies. (For more details on data type +conversion between QML and C++, see \l{qtqml-cppintegration-data.html}{Data +Type Conversion Between QML and C++}.) + + +\section2 Data Type Handling + +Any data that is transferred from C++ to QML, whether as a property value, a +method paramter or return value, or a signal parameter value, must be of a +type that is supported by the QML engine. + +By default, the engine supports a number of Qt C++ types and can automatically +convert them as appropriately when used from QML. Additionally, C++ classes +that are \l{Registering C++ types with the QML type system}{registered} with +the QML type system can be can be used as data types, as can their enums if +appropriately registered. See \l{qtqml-cppintegration-data.html}{Data Type +Conversion Between QML and C++} for details for further information. + + +\section2 Data Ownership + +When data is transferred from C++ to QML, the ownership of the data always +remains with C++. The exception to this rule is when a QObject is returned from +a C++ method: in this case, the QML engine assumes ownership of the object, +unless the ownership of the object has explicitly been set to remain with C++ by +invoking QQmlEngine::setObjectOwnership() with QQmlEngine::CppOwnership +specified. + +Furthermore, the QML engine respects the normal QObject parent ownership +semantics of Qt C++ objects, and will not ever take ownership of a QObject +instance which already has a parent. + +*/ \ No newline at end of file diff --git a/src/qml/doc/src/cppintegration/functions.qdoc b/src/qml/doc/src/cppintegration/functions.qdoc deleted file mode 100644 index 19dff3c..0000000 --- a/src/qml/doc/src/cppintegration/functions.qdoc +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** 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 qtqml-cppintegration-functions.html -\title Exposing C++ Functionality to QML -\brief Description of how to expose functionality defined in C++ to QML - - -// 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. - - - -\section1 Properties of Types Defined in C++ - -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: - -\table -\row -\li \snippet qml/qtbinding/properties-cpp/applicationdata.h 0 -\li \snippet qml/qtbinding/properties-cpp/MyItem.qml 0 -\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. - -\section1 Signals and Slots - -QML integrates with the normal Qt C++ signals and slots system. -Signal handlers may be defined in a QML object, to handle signals -emitted by that or other objects. Signals may also be defined -and emitted from QML, which can be connected to slots in C++. - -\section1 Method Invocation - -Methods of C++ types exposed to QML may be invoked so long as they -are flagged with Q_INVOKABLE. As noted above, if the function -returns a pointer to a QObject or a QObject-derived type, some care -must be taken to avoid unwanted ownership changes occurring. - - - - -\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/qml/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/qml/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{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/qml/cppextensions/referenceexamples/signal/birthdayparty.h 0 - The QML engine will create a handler for the \c partyStarted signal - called \c onPartyStarted. - \snippet examples/qml/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{onChanged}, 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/qml/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/qml/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 - - - - -\section1 Module API Functionality - -One of the simplest ways to expose C++ functionality to clients in -QML is by registering a QObject module API. This allows functionality -and data to be exposed in a namespace which is accessible from QML. -See the documentation about -\l{Defining QML Object Types from C++#Module-API-Type-Registration} -{Module API type registration} for information about module APIs, -and see the \l{qmlRegisterModuleApi()} documentation for details on how to -register and use a module API. - -A module API is instantiated and owned by the engine as a singleton. -Thus, it is more performant to implement common functionality in a module -API than in an instantiable, non-visual element. - -*/ diff --git a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc new file mode 100644 index 0000000..51e92b2 --- /dev/null +++ b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** 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 qtqml-cppintegration-interactqmlfromcpp.html +\title Interacting with QML Objects from C++ +\brief Description of how to load and access QML objects from C++ code + +All QML object types are QObject-derived types, whether they are internally +implemented by the engine or \l +{qtqml-cppintegration-definetypes.html}{defined by third-party +sources}. This means the QML engine can use the Qt \l{Meta Object System} to +dynamically instantiate any QML object type and inspect the created objects. + +This is useful for creating QML objects from C++ code, whether to display a QML +object that can be visually rendered, or to integrate non-visual QML object data +into a C++ application. Once a QML object is created, it can be inspected from +C++ in order to read and write to properties, invoke methods and receive signal +notifications. + + +\section1 Loading QML Objects from C++ + +A QML document can be loaded with QQmlComponent or QQuickView. QQmlComponent +loads a QML document as a C++ object that can then be modified from C++ code. +QQuickView also does this, but as QQuickView is a QWindow-derived class, the +loaded object will also be rendered into a visual display; QQuickView is +generally used to integrate a displayable QML object into an application's +user interface. + +For example, suppose there is a \c MyItem.qml file that looks like this: + +\snippet qml/qtbinding/loading/MyItem.qml start +\snippet qml/qtbinding/loading/MyItem.qml end + +This QML document can be loaded with QQmlComponent or QQuickView with the +following +C++ code. Using a QQmlComponent requires calling QQmlComponent::create() to +create +a new instance of the component, while a QQuickView automatically creates an +instance of the +component, which is accessible via QQuickView::rootObject(): + +\table +\row +\li +\snippet qml/qtbinding/loading/main.cpp QQmlComponent-a +\dots 0 +\snippet qml/qtbinding/loading/main.cpp QQmlComponent-b +\li +\snippet qml/qtbinding/loading/main.cpp QQuickView +\endtable + +This \c object is the instance of the \c MyItem.qml component that has been +created. You can now modify the item's properties using QObject::setProperty() +or QQmlProperty: + +\snippet qml/qtbinding/loading/main.cpp properties + +Alternatively, you can cast the object to its actual type and call methods with +compile-time safety. In this case the base object of \c MyItem.qml is an +\l Item, which is defined by the QQuickItem class: + +\snippet qml/qtbinding/loading/main.cpp cast + +You can also connect to any signals or call methods defined in the component +using QMetaObject::invokeMethod() and QObject::connect(). See \l {Exchanging +data between QML and C++} below for further details. + + +\section1 Accessing Loaded QML Objects by Object Name + +QML components are essentially object trees with children that have siblings and +their own children. Child objects of QML components can be located using the +QObject::objectName property with QObject::findChild(). For example, if the root +item in \c MyItem.qml had a child \l Rectangle item: + +\snippet qml/qtbinding/loading/MyItem.qml start +\codeline +\snippet qml/qtbinding/loading/MyItem.qml child +\snippet qml/qtbinding/loading/MyItem.qml end + +The child could be located like this: + +\snippet qml/qtbinding/loading/main.cpp findChild + +Note that an object may have multiple children with the same \c objectName. +For example, \l ListView creates multiple instances of its delegate, so if its +delegate is declared with a particular objectName, the \l ListView will have +multiple children with the same \c objectName. In this case, +QObject::findChildren() can be used to find all children with a matching +\c objectName. + +\warning While it is possible to use C++ to access and manipulate QML objects +deep into the object tree, we recommend that you do not take this approach +outside of application testing and prototyping. One strength of QML and C++ +integration is the ability to implement the QML user interface separately +from the C++ logic and dataset backend, and this strategy breaks if the C++ +side reaches deep into the QML components to manipulate them directly. This +would make it difficult to, for example, swap a QML view component for +another view, if the new component was missing a required \c objectName. It +is better for the C++ implementation to know as little as possible about the +QML user interface implementation and the composition of the QML object tree. + + +\section1 Accessing Members of a QML Object Type from C++ + +\section2 Properties + +Any properties declared in a QML object are automatically accessible from C++. +Given a QML item like this: + +\snippet qml/qtbinding/properties-qml/MyItem.qml 0 + +The value of the \c someNumber property can be set and read using QQmlProperty, +or QObject::setProperty() and QObject::property(): + +\snippet qml/qtbinding/properties-qml/main.cpp 0 + +You should always use QObject::setProperty(), QQmlProperty or +QMetaProperty::write() to change a QML property value, to ensure the QML +engine is made aware of the property change. For example, say you have a +custom element \c PushButton with a \c buttonText property that internally +reflects the value of a \c m_buttonText member variable. Modifying the member +variable directly like this is not a good idea: + +\badcode +// BAD! +QQmlComponent component(engine, "MyButton.qml"); +PushButton *button = qobject_cast(component.create()); +button->m_buttonText = "Click me"; +\endcode + +Since the value is changed directly, this bypasses Qt's \l{The Meta-Object +System}{meta-object system} and the QML engine is not made aware of the +property change. This means property bindings to \c buttonText would not be +updated, and any \c onButtonTextChanged handlers would not be called. + +\section2 Methods + +All QML methods are exposed to the meta-object system and can be called from C++ +using QMetaObject::invokeMethod(). Method parameters and return values passed +from QML are always translated into QVariant values in C++. + +Here is a C++ application that calls a QML method using +QMetaObject::invokeMethod(): + +\table +\row +\li \snippet qml/qtbinding/functions-qml/MyItem.qml 0 +\li \snippet qml/qtbinding/functions-qml/main.cpp 0 +\endtable + +Notice the Q_RETURN_ARG() and Q_ARG() arguments for QMetaObject::invokeMethod() +must be specified as QVariant types, as this is the generic data type used for +QML method parameters and return values. + + +\section2 Signals And Slots + +All QML signals are automatically available to C++, and can be connected to +using QObject::connect() like any ordinary Qt C++ signal. In return, any C++ +signal can be received by a QML object using +\l {Signal Handlers}{signal handlers}. + +Here is a QML component with a signal named \c qmlSignal that is emitted with +a string-type parameter. This signal is connected to a C++ object's slot using +QObject::connect(), so that the \c cppSlot() method is called whenever the +\c qmlSignal is emitted: + +\table +\row +\li +\snippet qml/qtbinding/signals-qml/MyItem.qml 0 +\li +\snippet qml/qtbinding/signals-qml/myclass.h 0 +\codeline +\snippet qml/qtbinding/signals-qml/main.cpp 0 +\endtable + +When a QML object type is used as a signal parameter, the parameter should +use \l var as the type, and the value should be received in C++ using the +QVariant type: + +\table +\row +\li + +\qml + // MyItem.qml + import QtQuick 2.0 + + Item { + id: item + width: 100; height: 100 + + signal qmlSignal(var anObject) + + MouseArea { + anchors.fill: parent + onClicked: item.qmlSignal(item) + } + } +\endqml + +\li +\code + class MyClass : public QObject + { + Q_OBJECT + public slots: + void cppSlot(const QVariant &v) { + qDebug() << "Called the C++ slot with value:" << v; + + QQuickItem *item = qobject_cast(v.value()); + qDebug() << "Item dimensions:" << item->width() << item->height(); + } + }; + + int main(int argc, char *argv[]) { + QApplication app(argc, argv); + + QQuickView view(QUrl::fromLocalFile("MyItem.qml")); + QObject *item = view.rootObject(); + + MyClass myClass; + QObject::connect(item, SIGNAL(qmlSignal(QVariant)), + &myClass, SLOT(cppSlot(QVariant))); + + view.show(); + return app.exec(); + } +\endcode +\endtable + +*/ \ No newline at end of file diff --git a/src/qml/doc/src/cppintegration/registercpptypes.qdoc b/src/qml/doc/src/cppintegration/registercpptypes.qdoc deleted file mode 100644 index 051bb5b..0000000 --- a/src/qml/doc/src/cppintegration/registercpptypes.qdoc +++ /dev/null @@ -1,534 +0,0 @@ -/**************************************************************************** -** -** 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 qtqml-cppintegration-registercpptypes.html -\title Defining QML Object Types from C++ -\brief Description of how to register C++ types with the QML type system - - - - -\section1 Defining New QML Elements - -While new QML elements can be \l {Defining New Components}{defined in QML}, they can also be -defined by C++ classes; in fact, many of the core \l {QML Elements} are implemented through -C++ classes. When you create a QML object using one of these elements, you are simply creating an -instance of a QObject-based C++ class and setting its properties. - -To create a visual item that fits in with the Qt Quick elements, base your class off \l QQuickItem instead of QObject directly. -You can then implement your own painting and functionality like any other QGraphicsObject. Note that QGraphicsItem::ItemHasNoContents is set by default on QQuickItem because -it does not paint anything; you will need to clear this if your item is supposed to paint anything (as opposed to being solely for input handling or logical grouping). - -For example, here is an \c ImageViewer class with an \c image URL property: - -\snippet qml/qtbinding/newelements/imageviewer.h 0 - -Aside from the fact that it inherits QQuickItem, this is an ordinary class that could -exist outside of QML. However, once it is registered with the QML engine using qmlRegisterType(): - -\snippet qml/qtbinding/newelements/main.cpp register - -Then, any QML code loaded by your C++ application or \l{QQmlExtensionPlugin}{plugin} can create and manipulate -\c ImageViewer objects: - -\snippet qml/qtbinding/newelements/standalone.qml 0 - - -It is advised that you avoid using QGraphicsItem functionality beyond the properties documented in QQuickItem. -This is because the GraphicsView backend is intended to be an implementation detail for QML, so the QtQuick items can be moved to faster backends as they become available with no change from a QML perspective. -To minimize any porting requirements for custom visual items, try to stick to the documented properties in QQuickItem where possible. Properties QQuickItem inherits but doesn't document are classed as implementation details; they are not officially supported and may disappear between releases. - -Note that custom C++ types do not have to inherit from QQuickItem; this is only necessary if it is -a displayable item. If the item is not displayable, it can simply inherit from QObject. - -For more information on defining new QML elements, see the \l {Tutorial: Extending QML with C++} -{Writing QML extensions with C++} tutorial and the -\l{Extending QML with C++} reference documentation. - -\note If a C++ class which defines a QML type is declared -inside a namespace, then the namespace name has to be included in all -references to the class name (that is, in Q_PROPERTY declarations and the -associated property getter and setter function prototypes, and also in -Q_INVOKABLE function prototypes) within type declarations in that namespace. - -As an example of an incorrect, unqualified type declaration, if you have the -following: - -\code -// namespacedtype.h -namespace ExampleNamespace { - class ExampleType : public QObject - { - Q_OBJECT - Q_PROPERTY(ExampleType* sibling READ sibling WRITE setSibling) - - public: - ExampleType* sibling() const; - void setSibling(ExampleType* sib); - - Q_INVOKABLE ExampleType* findSiblingWithName(const QString &name); - }; -} - -//namespacedtype.cpp -#include "namespacedtype.h" -ExampleNamespace::ExampleType* ExampleNamespace::ExampleType::sibling() const -{ - return 0; // dummy implementation -} -void ExampleNamespace::ExampleType::setSibling(ExampleNamespace::ExampleType* sib) -{ - Q_UNUSED(sib); // dummy implementation -} -ExampleNamespace::ExampleType* ExampleNamespace::ExampleType::findSiblingWithName(const QString &name) -{ - return 0; // dummy implementation -} - -void registerTypes() -{ - qmlRegisterType("Example", 1, 0, "ExampleType"); -} -\endcode - -And you attempt to use the type (after calling \c registerTypes()) in QML like so: - -\qml -import QtQuick 2.0 -import Example 1.0 - -Item { - property ExampleType nt: ExampleType { } - - width: 200 - height: 100 - Text { - anchors.centerIn: parent - text: "sibling = " + nt.sibling - } -} -\endqml - -You will receive the warning: \tt{QMetaProperty::read: Unable to handle -unregistered datatype 'ExampleType*' for property -'ExampleNamespace::ExampleType::sibling'}, and you will not be able to use the -"sibling" property in QML. - -To ensure that it works properly, whenever \c ExampleType is referred to (as a -property type, parameter type or return type) in the type declaration, it must -be fully qualified (with its namespace) in order to be processed correctly by -the QML metatype system, as shown below: - -\code -// namespacedtype.h -namespace ExampleNamespace { - class ExampleType : public QObject - { - Q_OBJECT - Q_PROPERTY(ExampleNamespace::ExampleType* sibling READ sibling WRITE setSibling) - - public: - ExampleNamespace::ExampleType* sibling() const; - void setSibling(ExampleNamespace::ExampleType* sib); - - Q_INVOKABLE ExampleNamespace::ExampleType* findSiblingWithName(const QString &name); - }; -} - -//namespacedtype.cpp -#include "namespacedtype.h" -ExampleNamespace::ExampleType* ExampleNamespace::ExampleType::sibling() const -{ - return 0; // dummy implementation -} -void ExampleNamespace::ExampleType::setSibling(ExampleNamespace::ExampleType* sib) -{ - Q_UNUSED(sib); // dummy implementation -} -ExampleNamespace::ExampleType* ExampleNamespace::ExampleType::findSiblingWithName(const QString &name) -{ - return 0; // dummy implementation -} - -void registerTypes() -{ - qmlRegisterType("Example", 1, 0, "ExampleType"); -} -\endcode - -The type will now be able to be used normally from within QML documents. - -\section1 Subclassing QQmlParserStatus - - Often, to develop high performance elements it is helpful to know more about - the status of the QML engine. For example, it might be beneficial to delay - initializing some costly data structures until after all the properties have - been set. - - The QML engine defines an interface class called QQmlParserStatus, - which contains a number of virtual methods that are invoked at various - stages during component instantiation. To receive these notifications, an - element implementation inherits QQmlParserStatus and notifies the Qt - meta system using the Q_INTERFACES() macro. - - \code - class Example : public QObject, public QQmlParserStatus - { - Q_OBJECT - Q_INTERFACES(QQmlParserStatus) - public: - virtual void componentComplete() - { - qDebug() << "Woohoo! Now to do my costly initialization"; - } - }; - \endcode - - - - - - -\target register-c++-type -\section1 Register a Type - -The \l{QQmlEngine}{QML engine} can instantiate any Qt C++ construct -such as \l{The Property System}{properties}, functions, and data models into -the QML context allowing the constructs to be accessible from within QML. - - - In an application or a \l{QML Plugins}{plugin}, the \c qmlRegisterType - template will register a class to the QML engine. - -\code -template -int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) -\endcode - - \l qmlRegisterType() registers the C++ type \a T with the QML system, and - makes it available to the QML context under the name \c qmlName in library - \c uri version \c versionMajor.versionMinor. The \c qmlName can be the same - as the C++ type name. - - Suppose that a \c Person class defined in a C++ is to be exposed into the - QML context. The class must be a subclass of \l{QObject} and have a default - constructor. The \l{The Property System}{properties} created with the - Q_PROPERTY macro are visible in the QML context as well. - \snippet examples/qml/cppextensions/referenceexamples/adding/person.h 0 - - The application registers the class to the runtime with the - \l{qmlRegisterType()}. - - \snippet examples/qml/cppextensions/referenceexamples/adding/main.cpp 0 - - The Person type is then imported with the \c "People 1.0" module and its - properties are accessible in a QML file. - \snippet examples/qml/cppextensions/referenceexamples/adding/example.qml 0 - - The \l {Extending QML - Adding Types Example}{Adding Types} example - demonstrates as usage of the \l qmlRegisterType(). - - Alternatively, these functions provide a way for other types of C++ types - to be visible in the QML context. - \list - \li \l qmlRegisterModuleApi() is suited for registering either a QJSValue - or QObject module API (shared instance) into a namespace - \li \l qmlRegisterUncreatableType() is suited for attached - properties and enum types. - \li \l qmlRegisterTypeNotAvailable() is for - reserving a namespace and suited for generating useful errors. - \li \l qmlRegisterInterface() - for registering base or abstract classes for - \l{qml-c++-coercion}{coercion and inheritance}. This is useful for general - Qt objects or \l{Qt Objects and Interfaces}{pointers} to objects. - \li \l qmlRegisterExtendedType() - for \l{qml-c++-extension}{extended types} - \endlist - - \section2 Qt Objects and Interfaces - QML can bind to complex objects such as pointers to objects or lists. As QML - is typesafe, the \l{QQmlEngine}{QML engine} ensures that only - valid types are assigned to these properties. - - The QML engine treats pointers to objects or Qt interfaces the same - way as regular properties. Thus, the lists or pointers are created as - properties using the Q_PROPERTY() macro. - - \snippet examples/qml/cppextensions/referenceexamples/properties/birthdayparty.h 1 - - The \c host is an \l{qml-expose-properties}{exposed property} that can bind - to objects or lists of objects. The property type, in this case \c Person, - must be \l{Creating QML Object Types from C++}{registered} into the runtime. - - QML also supports assigning Qt interfaces. To assign to a property whose - type is a Qt interface pointer, the interface must also be registered with - QML. As they cannot be instantiated directly, registering a Qt interface is - different from registering a new QML type. The following function is used - instead: - - \code - template - int qmlRegisterInterface(const char *typeName) - \endcode - - This function registers the C++ interface \a T with the QML system as \a - typeName. - - Following registration, QML can \l{qml-c++-coercion}{coerce} objects that - implement this interface for assignment to appropriately typed properties. - -\section2 Module API Type Registration - - Module APIs allow you to expose properties, signals and slots in a namespace - without requiring the client to manually instantiate an object instance. - QObject module APIs in particular are an efficient and convenient way to - provide functionality or global property values to clients. - - Note that module APIs do not have an associated QQmlContext as they are - shared across all contexts in an engine. QObject module API instances - are constructed and owned by the QQmlEngine, and will be destroyed when - the engine is destroyed. - - A QObject module API can be interacted with in a manner simlar to any - other QObject or instantiated element. That is, Q_PROPERTYs of QObject - module APIs may be bound to, and Q_INVOKABLE functions of QObject module - APIs may be used in signal handler expressions. This makes module APIs - an ideal way to implement styling or theming, and they can also be used - instead of ".pragma library" script imports to store global state or to - provide global functionality. - - Once registered, a QObject module API may be used as any other QObject - instance exposed to QML. The following example assumes that a QObject - module API was registered into the "MyThemeModule" namespace with version - 1.0, where that QObject has a QColor "color" Q_PROPERTY: - - \qml - import MyThemeModule 1.0 as Theme - - Rectangle { - color: Theme.color // binding. - } - \endqml - - A QJSValue may also be exposed as a module API, however clients should - be aware that properties of such a module API cannot be bound to. - - See \l{qmlRegisterModuleApi()} for more information on how implement and - register a new module API, and how to use an existing module API. - -\section1 Type Revisions and Versions - - Type revisions and versions allow new properties or methods to exist in the - new version while remaining compatible with previous versions. - - Consider these two QML files: - \code - // main.qml - import QtQuick 1.0 - Item { - id: root - MyComponent {} - } - \endcode - - \code - // MyComponent.qml - import MyModule 1.0 - CppItem { - value: root.x - } - \endcode - where \c CppItem maps to the C++ class \c QCppItem. - - If the author of QCppItem adds a \c root property to QCppItem in a new - version of the module, \c root.x now resolves to a different value because - \c root is also the \c id of the top level component. The author could - specify that the new \c root property is available from a specific minor - version. This permits new properties and features to be added to existing - elements without breaking existing programs. - - The REVISION tag is used to mark the \c root property as added in revision 1 - of the class. Methods such as Q_INVOKABLE's, signals and slots can also be - tagged for a revision using the \c Q_REVISION(x) macro: - - \code - class CppElement : public BaseObject - { - Q_OBJECT - Q_PROPERTY(int root READ root WRITE setRoot NOTIFY rootChanged REVISION 1) - - signals: - Q_REVISION(1) void rootChanged(); - }; - \endcode - - To register the new class revision to a particular version the following function is used: - - \code - template - int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) - \endcode - - To register \c CppElement version 1 for \c {MyModule 1.1}: - - \code - qmlRegisterType("MyModule", 1, 1, "CppElement") - \endcode - - \c root is only available when MyModule 1.1 is imported. - - For the same reason, new elements introduced in later versions should use - the minor version argument of qmlRegisterType. - - This feature of the language allows for behavioural changes to be made - without breaking existing applications. Consequently QML module authors - should always remember to document what changed between minor versions, and - QML module users should check that their application still runs correctly - before deploying an updated import statement. - - You may also register the revision of a base class that your module depends upon - using the qmlRegisterRevision() function: - - \code - template - int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) - - template - int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) - \endcode - - For example, if \c BaseObject is changed and now has a revision 1, you can specify that - your module uses the new revision: - - \code - qmlRegisterRevision("MyModule", 1, 1); - \endcode - - This is useful when deriving from base classes not declared as part of your - module, e.g. when extending classes from the QtQuick library. - - The revision feature of QML allows for behavioral changes without breaking - existing applications. Consequently, QML module authors should always - remember to document what changed between minor versions, and QML module - users should check that their application still runs correctly before - deploying an updated import statement. - -\target qml-c++-coercion -\section1 Inheritance and Coercion - - QML supports C++ inheritance hierarchies and can freely coerce between - known, valid object types. This enables the creation of common base classes - that allow the assignment of specialized classes to object or list - properties. - - \snippet examples/qml/cppextensions/referenceexamples/coercion/example.qml 0 - - The QML snippet shown above assigns a \c Boy object to the \c - BirthdayParty's \c host property, and assigns three other objects to the \c - guests property. Both the \c host and the \c guests properties binds to the - \c Person type, but the assignment is valid as both the \c Boy and \c Girl - objects inherit from \c Person. - - To assign to a property, the property's type must have been - \l{Creating QML Object Types from C++}{registered} to the \l{QQmlEngine}{declarative - runtime}. If a type that acts purely as a base class that cannot be - instantiated from QML needs to be registered as well. The - \l qmlRegisterType() is useful for this occasion. - - \code - template - int qmlRegisterType() - \endcode - - This function registers the C++ type \a T with the QML system. The - parameterless call to the template function qmlRegisterType() does not - define a mapping between the C++ class and a QML element name, so the type - is not instantiable from QML, but it is available for type coercion. - - \snippet examples/qml/cppextensions/referenceexamples/coercion/main.cpp 0 - \snippet examples/qml/cppextensions/referenceexamples/coercion/main.cpp register boy girl - The \c Person class is registered withouth the parameters. Both the - \c Boy and \c Girl class derive from the \c Person class. - - Type \a T must inherit QObject, but there are no restrictions on whether it - is concrete or the signature of its constructor. - - QML will automatically coerce C++ types when assigning to either an object - property, or to a list property. Only if coercion fails does an assignment - error occur. - - The \l{Extending QML - Inheritance and Coercion Example}{Inheritance and Coercion Example} - shows the complete code used to create the \c Boy and \c Girl types. - -\target qml-c++-extension -\section1 Extension Objects - - \snippet examples/qml/cppextensions/referenceexamples/extended/example.qml 0 - - The \c leftMargin property is a new property to an existing C++ type, - \l QLineEdit, without modifying its source code. - - When integrating existing classes and technology into QML, APIs will - often need tweaking to fit better into the declarative environment. - Although the best results are usually obtained by modifying the original - classes directly, if this is either not possible or is complicated by some - other concerns, extension objects allow limited extension possibilities - without direct modifications. - - \e{Extension objects} add additional properties to an existing type. - Extension objects can only add properties, not signals or methods. An - extended type definition allows the programmer to supply an additional type, - known as the \e{extension type}, when registering the class. The - properties are transparently merged with the original target class when used - from within QML. - - The \l qmlRegisterExtendedType() is for registering extended types. Note - that it has two forms. - \code - template - int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) - - template - int qmlRegisterExtendedType() - \endcode - functions should be used instead of the regular \c qmlRegisterType() variations. - The arguments are identical to the corresponding non-extension registration functions, - except for the ExtendedT parameter which is the type - of the extension object. - - An extension class is a regular QObject, with a constructor that takes a - QObject pointer. However, the extension class creation is delayed until the - first extended property is accessed. The extension class is created and the - target object is passed in as the parent. When the property on the original - is accessed, the corresponding property on the extension object is used - instead. - - The \l{Extending QML - Extension Objects}{Extension Objects} example - demonstrates a usage of extension objects. - - - - -*/ diff --git a/src/qml/doc/src/cppintegration/reverse.qdoc b/src/qml/doc/src/cppintegration/reverse.qdoc deleted file mode 100644 index a4b4c8c..0000000 --- a/src/qml/doc/src/cppintegration/reverse.qdoc +++ /dev/null @@ -1,252 +0,0 @@ -/**************************************************************************** -** -** 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 qtqml-cppintegration-reverse.html -\title Interacting with QML Objects from C++ -\brief Description of how to interact with QML objects from C++ - -\section1 QML Objects, QObject and QMetaObject - -QML object types are, internally, QObject-derived types. Each type has an -associated QMetaObject, and all functions, properties and signals of an -instance of a QML object type can be accessed through the QMetaObject. - -\section1 Accessing QML Objects from C++ - -Once you have a pointer to a QML object in C++, you can access its properties, -invoke its functions, and connect to its signals. To get such a pointer, a -C++ developer may either inspect the object hierarchy directly, or be passed -a pointer to the QML object as an argument in a function call. - - - -\section2 Loading QML Components from C++ - -A QML document can be loaded with QQmlComponent or QQuickView. QQmlComponent -loads a QML component as a C++ object; QQuickView also does this, -but additionally loads the QML component directly into a QGraphicsView. It is convenient for loading -a displayable QML component into a QWidget-based application. - -For example, suppose there is a \c MyItem.qml file that looks like this: - -\snippet qml/qtbinding/loading/MyItem.qml start -\snippet qml/qtbinding/loading/MyItem.qml end - -This QML document can be loaded with QQmlComponent or QQuickView with the following -C++ code. Using a QQmlComponent requires calling QQmlComponent::create() to create -a new instance of the component, while a QQuickView automatically creates an instance of the -component, which is accessible via QQuickView::rootObject(): - -\table -\row -\li -\snippet qml/qtbinding/loading/main.cpp QQmlComponent-a -\dots 0 -\snippet qml/qtbinding/loading/main.cpp QQmlComponent-b -\li -\snippet qml/qtbinding/loading/main.cpp QQuickView -\endtable - -This \c object is the instance of the \c MyItem.qml component that has been created. You can now -modify the item's properties using QObject::setProperty() or QQmlProperty: - -\snippet qml/qtbinding/loading/main.cpp properties - -Alternatively, you can cast the object to its actual type and call functions with compile-time -safety. In this case the base object of \c MyItem.qml is an \l Item, which is defined by the -QQuickItem class: - -\snippet qml/qtbinding/loading/main.cpp cast - -You can also connect to any signals or call functions defined in the component using -QMetaObject::invokeMethod() and QObject::connect(). See \l {Exchanging data between QML and C++} -below for further details. - - - - -\section2 Object Name and findChild - -NOTE: this is only applicable to QML object types provided by the Qt Quick -module. - -QML components are essentially object trees with children that have siblings and their own children. -Child objects of QML components can be located using the QObject::objectName property with -QObject::findChild(). For example, if the root item in \c MyItem.qml had a child \l Rectangle item: - -\snippet qml/qtbinding/loading/MyItem.qml start -\codeline -\snippet qml/qtbinding/loading/MyItem.qml child -\snippet qml/qtbinding/loading/MyItem.qml end - -The child could be located like this: - -\snippet qml/qtbinding/loading/main.cpp findChild - -If \c objectName is used inside a delegate of a ListView, \l Repeater or some other -element that creates multiple instances of its delegates, there will be multiple children with -the same \c objectName. In this case, QObject::findChildren() can be used to find all children -with a matching \c objectName. - -\warning While it is possible to use C++ to access and manipulate QML objects deep into the -object tree, we recommend that you do not take this approach outside of application -testing and prototyping. One strength of QML and C++ integration is the ability to implement the -QML user interface separately from the C++ logic and dataset backend, and this strategy breaks if the -C++ side reaches deep into the QML components to manipulate them directly. This would make it difficult -to, for example, swap a QML view component for another view, if the new component was missing a -required \c objectName. It is better for the C++ implementation to know as little as possible about -the QML user interface implementation and the composition of the QML object tree. - -\section2 Passed as Arguments - -Any QML object may be passed as an argument to a Q_INVOKABLE C++ function -if that function has a pointer to a QObject as a parameter. The object -may be passed via its id, or via a JavaScript var which references that object. - -XXX TODO: snippet example. - -\section1 Properties - -Any properties declared in a QML object are automatically accessible from C++. Given a QML item -like this: - -\snippet qml/qtbinding/properties-qml/MyItem.qml 0 - -The value of the \c someNumber property can be set and read using QQmlProperty, or -QObject::setProperty() and QObject::property(): - -\snippet qml/qtbinding/properties-qml/main.cpp 0 - -You should always use QObject::setProperty(), QQmlProperty or QMetaProperty::write() to -change a QML property value, to ensure the QML engine is made aware of the property change. For example, -say you have a custom element \c PushButton with a \c buttonText property that internally reflects -the value of a \c m_buttonText member variable. Modifying the member variable directly like this is -not a good idea: - -\badcode -// BAD! -QQmlComponent component(engine, "MyButton.qml"); -PushButton *button = qobject_cast(component.create()); -button->m_buttonText = "Click me"; -\endcode - -Since the value is changed directly, this bypasses Qt's \l{The Meta-Object System}{meta-object system} -and the QML engine is not made aware of the property change. This means property bindings to -\c buttonText would not be updated, and any \c onButtonTextChanged handlers would not be called. - -\section1 Functions - -QML functions can be called from C++ and vice-versa. - -All QML functions are exposed to the meta-object system and can be called using -QMetaObject::invokeMethod(). Here is a C++ application that uses this to call a QML function: - -\table -\row -\li \snippet qml/qtbinding/functions-qml/MyItem.qml 0 -\li \snippet qml/qtbinding/functions-qml/main.cpp 0 -\endtable - -Notice the Q_RETURN_ARG() and Q_ARG() arguments for QMetaObject::invokeMethod() must be specified as -QVariant types, as this is the generic data type used for QML functions and return values. - -To call a C++ function from QML, the function must be either a Qt slot, or a function marked with -the Q_INVOKABLE macro, to be available to QML. In the following example, the QML code invokes -methods on the \c myObject object, which has been set using QQmlContext::setContextProperty(): - -\table -\row -\li -\snippet qml/qtbinding/functions-cpp/MyItem.qml 0 -\li -\snippet qml/qtbinding/functions-cpp/myclass.h 0 -\codeline -\snippet qml/qtbinding/functions-cpp/main.cpp 0 -\endtable - -QML supports the calling of overloaded C++ functions. If there are multiple C++ functions with the -same name but different arguments, the correct function will be called according to the number and -the types of arguments that are provided. - -\section1 Signals and Slots - -All QML signals are automatically available to C++, and can be connected to using QObject::connect() -like any ordinary Qt C++ signal. In return, any C++ signal can be received by a QML object using -\l {Signal Handlers}{signal handlers}. - -Here is a QML component with a signal named \c qmlSignal. This signal is connected to a C++ object's -slot using QObject::connect(), so that the \c cppSlot() method is called whenever the \c qmlSignal -is emitted: - -\table -\row -\li -\snippet qml/qtbinding/signals-qml/MyItem.qml 0 -\li -\snippet qml/qtbinding/signals-qml/myclass.h 0 -\codeline -\snippet qml/qtbinding/signals-qml/main.cpp 0 -\endtable - -To connect to Qt C++ signals from within QML, use a signal handler with the \c on syntax. -In the following example, the -QML code creates a \c ImageViewer object, and the \c imageChanged and \c loadingError signals of the -C++ object are connected to through \c onImagedChanged and \c onLoadingError signal handlers in QML: - -\table -\row -\li - -\snippet qml/qtbinding/signals-cpp/imageviewer.h start -\dots 4 -\snippet qml/qtbinding/signals-cpp/imageviewer.h end - -\li -\snippet qml/qtbinding/signals-cpp/standalone.qml 0 -\endtable - -(Note that if a signal has been declared as the NOTIFY signal for a property, QML allows it to be -received with an \c onChanged handler even if the signal's name does not follow the \c -Changed naming convention. In the above example, if the "imageChanged" signal was named -"imageModified" instead, the \c onImageChanged signal handler would still be called.) - -If, however, the object with the signal is not created from within the QML code, and the QML item only has a -reference to the created object - for example, if the object was set using -QQmlContext::setContextProperty() - then the \l Connections element can be used -instead to create the signal handler: - -\table -\row -\li \snippet qml/qtbinding/signals-cpp/main.cpp connections -\li \snippet qml/qtbinding/signals-cpp/MyItem.qml 0 -\endtable - -C++ signals can use enum values as parameters provided that the enum is declared in the -class that is emitting the signal, and that the enum is registered using Q_ENUMS. -See \l {Using enumerations of a custom type} below for details. - -*/ diff --git a/src/qml/doc/src/cppintegration/topic.qdoc b/src/qml/doc/src/cppintegration/topic.qdoc index 3b88c50..49b1aa0 100644 --- a/src/qml/doc/src/cppintegration/topic.qdoc +++ b/src/qml/doc/src/cppintegration/topic.qdoc @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ @@ -29,81 +29,118 @@ \title Integrating QML and C++ \brief Description of how to integrate QML and C++ code -QML was designed to allow tight integration with C++ code. This allows hybrid -applications to be developed where the user-interface (and perhaps some small -amount of application logic) is specified in QML documents with QML and -JavaScript, but the bulk of the application logic is implemented in C++. +QML is designed to be easily extensible through C++ code. The classes in the QtQml C++ module +enables QML objects to be loaded and manipulated from C++, and the nature of QML engine's +integration with Qt's \l{Meta Object System}{meta object system} enables C++ functionality to be +invoked directly from QML. This allows the development of hybrid applications which are implemented +with a mixture of QML, JavaScript and C++ code. -Applications with a C++ entry-point can instantiate a QQmlEngine directly, -can use the QML type registration functions, and access the properties of the -root QQmlContext directly. Applications which utilize a QML entry point (that -is, they are loaded via \l{qtquick-qmlscene.html}{qmlscene} or some other tool) -can provide \l{qtqml-modules-cppplugins.html}{C++ plugins} which can register -types and provide functionality. - -You may want to mix QML and C++ for a number of reasons. For example: +Integrating QML and C++ provides a variety of opportunities, including the ability to: \list -\li To use functionality defined in a C++ source (for example, when using a C++ Qt-based data model, or -calling functions in a third-party C++ library) -\li To access functionality in the QtQml or QtQuick modules (for example, to dynamically generate +\li Separate the user interface code from the application logic code, by implementing the former +with QML and JavaScript within \l{qtqml-documents-topic.html}{QML documents}, and the latter with +C++ +\li Use and invoke some C++ functionality from QML (for example, to invoke your application logic, +use a data model implemented in C++, or call some functions in a third-party C++ library) +\li Access functionality in the QtQml or QtQuick C++ API (for example, to dynamically generate images using QQuickImageProvider) -\li To write your own QML object types (whether for your applications, or for distribution to others) +\li Implement your own \l{qtqml-typesystem-objecttypes.html}{QML object types} from C++ +\unicode{0x2014} whether for use within your own specific application, or for distribution to others \endlist -There are a number of ways to extend your QML application through C++. For example, you could: +To provide some C++ data or functionality to QML, it must be made available from a QObject-derived +class. Due to the QML engine's integration with the meta object system, the properties, methods and +signals of any QObject-derived class are accessible from QML, as described in +\l{qtqml-cppintegration-exposecppattributes.html}{Exposing Attributes of C++ Types to QML}. Once the +required functionality is provided by such a class, it can be exposed to QML in a variety of ways: \list -\li Load a QML component and manipulate it (or its children) from C++ -\li Embed a C++ object and its properties directly into a QML component (for example, to make a -particular C++ object callable from QML, or to replace a dummy list model with a real data set) -\li Define new QML object types (through QObject-based C++ classes) and create them directly from your -QML code +\li The class can be +\l{qtqml-cppintegration-definetypes.html#registering-an-instantiable-object-type}{ +registered as an instantiable QML type}, so that it can be instantiated and used like any ordinary +\l{qtqml-typesystem-objecttypes.html}{QML object type} from QML code +\li The class can be registered as a +\l{qtqml-cppintegration-definetypes.html#registering-singleton-objects-with-a-module-api} +{Module API} so that a single instance of the class may be imported from QML code, allowing the +instance's properties, methods and signals to be accessed from QML +\li An instance of the class can be \l{qtqml-cppintegration-contextproperties.html}{embedded into +QML code} as a \e {context property} or \e {context object}, allowing the instance's properties, +methods and signals to be accessed from QML \endlist +These are the most common methods of accessing C++ functionality from QML code; for more options and +details, see the main documentation pages that are described in the sections further below. +Additionally, aside from the ability to access C++ functionality from QML, the Qt QML module also +provides ways to do the reverse and manipulate QML objects from C++ code. See +\l{qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++} for more +details. + +Finally, the C++ code may be integrated into either a C++ application or a C++ plugin depending on +whether it is to be distributed as a standalone application or a library. A plugin can be integrated +with a QML module that can then be imported and used by QML code in other applications; see +\l{qtqml-modules-cppplugins.html}{Providing Types and Functionality in a C++ Plugin} for more +information. + + +\section1 Exposing Attributes of C++ Classes to QML + +QML can easily be extended from C++ due to the QML engine's integration with the Qt meta object +system. This integration allows the properties, methods and signals of any QObject-derived class to +be accessible from QML: properties can be read and modified, methods can be invoked from JavaScript +expressions and signal handlers are automatically created for signals as necessary. Additionally, +enumeration values of a QObject-derived class are accessible from QML. + +See \l{qtqml-cppintegration-exposecppattributes.html}{Exposing Attributes of C++ Types to QML} for +more information. + + +\section1 Defining QML Types from C++ + +QML types can be defined in C++ and then registered with the \l{qtqml-typesystem-topic.html}{QML +type system}. This allows a C++ class to be instantiated as a \l {QML object type}, enabling custom +object types to be implemented in C++ and integrated into existing QML code. A C++ class may be also +registered for other purposes: for example, it could be registered as a \e {Module API} to enable a +single class instance to be imported by QML code, or it could be registered to enable the +enumeration values of a non-instantiable class to be accessible from QML. + +Additionally, the QtQml module provides mechanisms to define QML types that integrate with QML +concepts like attached properties and default properties. + +For more information on registering and creating custom QML types from C++, see the \l +{qtqml-cppintegration-definetypes.html}{Defining QML Types from C++} documentation. + -\section1 Exposing C++ Types to QML +\section1 Embedding C++ Objects into QML with Context Properties -QML types may be implemented in C++ and then exposed to the QML type system via -plugins or type registration. This is covered in more detail elsewhere in the -documentation; see the documentation regarding -\l{qtqml-cppintegration-registercpptypes.html} -{Registering C++ Types with the QML Type System} for more information on that -topic. +C++ objects and values can be embedded directly into the context (or \e scope) of loaded QML objects +using \e {context properties} and \e {context objects}. This is achieved through the QQmlContext +class provided by the QtQml module, which exposes data to the context of a QML component, allowing +data to be injected from C++ into QML. -For more information on the specifics of how to define C++ types for use in QML -(not merely how to expose types to the QML type system), see the documentation -about defining \l{qtqml-modules-cppplugins.html#creating-a-plugin} -{C++ types for use in QML}. +See \l{qtqml-cppintegration-contextproperties.html}{Embedding C++ Objects into QML with Context +Properties} for more information. -\section1 Exposing C++ Data to QML -Data from C++ may be exposed to QML via context properties, instance -properties, or by returning data from Q_INVOKABLE methods. For more -information about each of these approaches, and the ownership semantics -applicable to each, see the documentation on \l{qtqml-cppintegration-data.html} -{Exposing C++ Data to QML}. +\section1 Interacting with QML Objects from C++ -\section1 Exposing C++ Functions to QML +QML object types can be instantiated from C++ and inspected in order to access their properties, +invoke their methods and receive their signal notifications. This is possible due to the fact that +all QML object types are implemented using QObject-derived classes, enabling the QML engine to +dynamically load and introspect objects through the Qt meta object system. -Functions from C++ may be exposed to QML via signals and slots, by tagging a -function declaration with the Q_INVOKABLE macro, or by registering the C++ type -as a module API and installing that module API into a particular namespace. -For more information about these approaches, see the documentation on -\l{qtqml-cppintegration-functions.html}{Exposing C++ Functionality to QML}. +For more information on accessing QML objects from C++, see the documentation on +\l{qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++}. -\section1 Interacting with Objects Defined in QML from C++ -Most properties of an object defined in QML may be accessed via -QQmlProperty::read() or QObject::property(). If the property is a list -property, QQmlListReference may be used instead. +\section1 Data Type Conversion Between QML and C++ -All methods of an object defined in QML may be invoked using the -QMetaObject::invokeMethod() function. This includes dynamic methods and signal -handlers. +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 from QML or C++, providing the data types involved are +known to the engine. -For more information about accessing QML objects from C++, see the -documentation on \l{qtqml-cppintegration-reverse.html} -{Interacting with Objects Defined in QML from C++}. +See \l{qtqml-cppintegration-data.html}{Data Type Conversion Between QML and C++} for information on +the built-in types supported by the engine and how these types are converted for use when exchanged +between QML and C++. */ diff --git a/src/qml/doc/src/qtqml.qdoc b/src/qml/doc/src/qtqml.qdoc index 6d655a3..8a5813f 100644 --- a/src/qml/doc/src/qtqml.qdoc +++ b/src/qml/doc/src/qtqml.qdoc @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/ @@ -85,7 +85,7 @@ types, animation classes, and canvas integration) for the QML language. \li \l{qtqml-typesystem-objecttypes.html}{QML Object Types} \list \li \l{qtqml-documents-definetypes.html}{Defining Object Types from QML} - \li \l{qtqml-cppintegration-registercpptypes.html}{Defining Object Types from C++} + \li \l{qtqml-cppintegration-definetypes.html}{Defining Object Types from C++} \endlist \li \l{qtqml-typesystem-topic.html#property-modifier-types}{Property Modifier Types} \endlist @@ -130,10 +130,11 @@ types, animation classes, and canvas integration) for the QML language. \li \l{qtqml-cppintegration-topic.html}{Integrating QML and C++} \list - \li \l{qtqml-cppintegration-registercpptypes.html}{Defining QML Object Types from C++} - \li \l{qtqml-cppintegration-data.html}{Exposing C++ Data to QML} - \li \l{qtqml-cppintegration-functions.html}{Exposing C++ Functionality to QML} - \li \l{qtqml-cppintegration-reverse.html}{Interacting with Objects defined in QML from C++} + \li \l{qtqml-cppintegration-exposecppattributes.html}{Exposing Attributes of C++ Classes to QML} + \li \l{qtqml-cppintegration-definetypes.html}{Defining QML Types from C++} + \li \l{qtqml-cppintegration-contextproperties.html}{Embedding C++ Objects into QML with Context Properties} + \li \l{qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++} + \li \l{qtqml-cppintegration-data.html}{Data Type Conversion Between QML and C++} \endlist \endlist diff --git a/src/qml/doc/src/typesystem/objecttypes.qdoc b/src/qml/doc/src/typesystem/objecttypes.qdoc index f2715b3..9d8f636 100644 --- a/src/qml/doc/src/typesystem/objecttypes.qdoc +++ b/src/qml/doc/src/typesystem/objecttypes.qdoc @@ -44,7 +44,7 @@ Custom QML object types can be defined by creating a .qml file that defines the type, as discussed in \l {qtqml-documents-definetypes.html} {Documents as QML object type definitions}, or by defining a QML type from C++ and registering the type with the QML engine, as discussed in -\l{qtqml-registercpptypes.html}{Registering C++ Types with the QML Type System}. +\l{qtqml-cppintegration-definetypes.html}{Defining QML Types from C++}. \section1 Creating Object Types from QML @@ -130,7 +130,7 @@ functions which each allow different use-cases to be fulfilled. \endlist For more information on this topic, see the documentation regarding -\l{qtqml-cppintegration-registercpptypes.html}{Creating QML Object Types from C++}. +\l{qtqml-cppintegration-definetypes.html}{Defining QML Types from C++}. The QML type-system relies on imports, plugins and extensions being installed into a known import path. Plugins may be provided by third-party developers -- 2.7.4