aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
diff options
context:
space:
mode:
authorBea Lam <bea.lam@nokia.com>2012-07-23 17:45:40 +1000
committerQt by Nokia <qt-info@nokia.com>2012-07-25 09:31:57 +0200
commit28def0bdd084989c17a157e0c4ab80c259081caa (patch)
tree5197bc3e89aff301d367738aa868cb226dc65fd7 /src/qml/doc/src/cppintegration/exposecppattributes.qdoc
parent14985d7b4347ed422358f963ae184f4dcb22f66f (diff)
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 <christopher.adams@nokia.com>
Diffstat (limited to 'src/qml/doc/src/cppintegration/exposecppattributes.qdoc')
-rw-r--r--src/qml/doc/src/cppintegration/exposecppattributes.qdoc506
1 files changed, 506 insertions, 0 deletions
diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
new file mode 100644
index 0000000000..6d8718ea2e
--- /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 <property>Changed
+where \c <property> is the name of the property. The associated property
+change signal handler generated by the QML engine will always take the form
+\c on<Property>Changed, 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<T> 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<Message> messages READ messages)
+public:
+ QQmlListProperty<Message> messages() const;
+
+private:
+ static void append_message(QQmlListProperty<Message> *list, Message *msg);
+
+ QList<Message *> m_messages;
+};
+\endcode
+
+The MessageBoard::messages() function simply creates and returns a
+QQmlListProperty from its QList<T> \c m_messages member, passing the
+appropriate list modification functions as required by the QQmlListProperty
+constructor:
+
+\code
+QQmlListProperty<Message> MessageBoard::messages()
+{
+ return QQmlListProperty<Message>(this, 0, &MessageBoard::append_message);
+}
+
+void MessageBoard::append_message(QQmlListProperty<Message> *list, Message *msg)
+{
+ MessageBoard *msgBoard = qobject_cast<MessageBoard *>(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<Signal> where \c <Signal> 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