diff options
Diffstat (limited to 'src/qml/doc/src/bindings/qmltypes.qdoc')
-rw-r--r-- | src/qml/doc/src/bindings/qmltypes.qdoc | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/src/qml/doc/src/bindings/qmltypes.qdoc b/src/qml/doc/src/bindings/qmltypes.qdoc new file mode 100644 index 0000000000..b4c52988cb --- /dev/null +++ b/src/qml/doc/src/bindings/qmltypes.qdoc @@ -0,0 +1,356 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +/*! +\page qml-c++types.html +\title C++ Types as QML Types +\brief exposing Qt C++ types into the QML engine + +The \l{The QML Engine}{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. + +\target register-c++-type +\section1 Register a Type + + In an application or a \l{QML Plugins}{plugin}, the \c qmlRegisterType + template will register a class to the QML engine. + +\code +template<typename T> +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 declarative/cppextensions/referenceexamples/adding/person.h 0 + + The application registers the class to the runtime with the + \l{qmlRegisterType()}. + + \snippet declarative/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 declarative/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{The QML Engine}{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/declarative/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{register-c++-type}{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<typename T> + 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. + +\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<typename T, int metaObjectRevision> + 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<QCppElement,1>("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<typename T, int metaObjectRevision> + int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) + \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<BaseObject,1>("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/declarative/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{register-c++-type}{registered} to the \l{The QML Engine}{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<typename T> + 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/declarative/cppextensions/referenceexamples/coercion/main.cpp 0 + \snippet examples/declarative/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/declarative/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<typename T, typename ExtendedT> + int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) + + template<typename T, typename ExtendedT> + 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. + +\section1 Property Value Sources + +\snippet examples/declarative/cppextensions/referenceexamples/valuesource/example.qml 0 +\snippet examples/declarative/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. + +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. + +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/declarative/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/declarative/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 0 +\snippet examples/declarative/cppextensions/referenceexamples/valuesource/happybirthdaysong.h 1 +\snippet examples/declarative/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. + +\section1 Optimization and Other Considerations + +The \l{qml-engine-optimization}{ QML Engine} article suggests possible +optimization considerations as memory management and QVariant type usages. + +*/ |