1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the documentation of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** GNU Free Documentation License
10 ** Alternatively, this file may be used under the terms of the GNU Free
11 ** Documentation License version 1.3 as published by the Free Software
12 ** Foundation and appearing in the file included in the packaging of
16 ** Alternatively, this file may be used in accordance with the terms
17 ** and conditions contained in a signed written agreement between you
26 ****************************************************************************/
28 \page qtqml-cppintegration-reverse.html
29 \title Interacting with QML Objects from C++
30 \brief Description of how to interact with QML objects from C++
32 \section1 QML Objects, QObject and QMetaObject
34 QML object types are, internally, QObject-derived types. Each type has an
35 associated QMetaObject, and all functions, properties and signals of an
36 instance of a QML object type can be accessed through the QMetaObject.
38 \section1 Accessing QML Objects from C++
40 Once you have a pointer to a QML object in C++, you can access its properties,
41 invoke its functions, and connect to its signals. To get such a pointer, a
42 C++ developer may either inspect the object hierarchy directly, or be passed
43 a pointer to the QML object as an argument in a function call.
47 \section2 Loading QML Components from C++
49 A QML document can be loaded with QQmlComponent or QQuickView. QQmlComponent
50 loads a QML component as a C++ object; QQuickView also does this,
51 but additionally loads the QML component directly into a QGraphicsView. It is convenient for loading
52 a displayable QML component into a QWidget-based application.
54 For example, suppose there is a \c MyItem.qml file that looks like this:
56 \snippet qml/qtbinding/loading/MyItem.qml start
57 \snippet qml/qtbinding/loading/MyItem.qml end
59 This QML document can be loaded with QQmlComponent or QQuickView with the following
60 C++ code. Using a QQmlComponent requires calling QQmlComponent::create() to create
61 a new instance of the component, while a QQuickView automatically creates an instance of the
62 component, which is accessible via QQuickView::rootObject():
67 \snippet qml/qtbinding/loading/main.cpp QQmlComponent-a
69 \snippet qml/qtbinding/loading/main.cpp QQmlComponent-b
71 \snippet qml/qtbinding/loading/main.cpp QQuickView
74 This \c object is the instance of the \c MyItem.qml component that has been created. You can now
75 modify the item's properties using QObject::setProperty() or QQmlProperty:
77 \snippet qml/qtbinding/loading/main.cpp properties
79 Alternatively, you can cast the object to its actual type and call functions with compile-time
80 safety. In this case the base object of \c MyItem.qml is an \l Item, which is defined by the
83 \snippet qml/qtbinding/loading/main.cpp cast
85 You can also connect to any signals or call functions defined in the component using
86 QMetaObject::invokeMethod() and QObject::connect(). See \l {Exchanging data between QML and C++}
87 below for further details.
92 \section2 Object Name and findChild
94 NOTE: this is only applicable to QML object types provided by the Qt Quick
97 QML components are essentially object trees with children that have siblings and their own children.
98 Child objects of QML components can be located using the QObject::objectName property with
99 QObject::findChild(). For example, if the root item in \c MyItem.qml had a child \l Rectangle item:
101 \snippet qml/qtbinding/loading/MyItem.qml start
103 \snippet qml/qtbinding/loading/MyItem.qml child
104 \snippet qml/qtbinding/loading/MyItem.qml end
106 The child could be located like this:
108 \snippet qml/qtbinding/loading/main.cpp findChild
110 If \c objectName is used inside a delegate of a ListView, \l Repeater or some other
111 element that creates multiple instances of its delegates, there will be multiple children with
112 the same \c objectName. In this case, QObject::findChildren() can be used to find all children
113 with a matching \c objectName.
115 \warning While it is possible to use C++ to access and manipulate QML objects deep into the
116 object tree, we recommend that you do not take this approach outside of application
117 testing and prototyping. One strength of QML and C++ integration is the ability to implement the
118 QML user interface separately from the C++ logic and dataset backend, and this strategy breaks if the
119 C++ side reaches deep into the QML components to manipulate them directly. This would make it difficult
120 to, for example, swap a QML view component for another view, if the new component was missing a
121 required \c objectName. It is better for the C++ implementation to know as little as possible about
122 the QML user interface implementation and the composition of the QML object tree.
124 \section2 Passed as Arguments
126 Any QML object may be passed as an argument to a Q_INVOKABLE C++ function
127 if that function has a pointer to a QObject as a parameter. The object
128 may be passed via its id, or via a JavaScript var which references that object.
130 XXX TODO: snippet example.
134 Any properties declared in a QML object are automatically accessible from C++. Given a QML item
137 \snippet qml/qtbinding/properties-qml/MyItem.qml 0
139 The value of the \c someNumber property can be set and read using QQmlProperty, or
140 QObject::setProperty() and QObject::property():
142 \snippet qml/qtbinding/properties-qml/main.cpp 0
144 You should always use QObject::setProperty(), QQmlProperty or QMetaProperty::write() to
145 change a QML property value, to ensure the QML engine is made aware of the property change. For example,
146 say you have a custom element \c PushButton with a \c buttonText property that internally reflects
147 the value of a \c m_buttonText member variable. Modifying the member variable directly like this is
152 QQmlComponent component(engine, "MyButton.qml");
153 PushButton *button = qobject_cast<PushButton*>(component.create());
154 button->m_buttonText = "Click me";
157 Since the value is changed directly, this bypasses Qt's \l{The Meta-Object System}{meta-object system}
158 and the QML engine is not made aware of the property change. This means property bindings to
159 \c buttonText would not be updated, and any \c onButtonTextChanged handlers would not be called.
163 QML functions can be called from C++ and vice-versa.
165 All QML functions are exposed to the meta-object system and can be called using
166 QMetaObject::invokeMethod(). Here is a C++ application that uses this to call a QML function:
170 \li \snippet qml/qtbinding/functions-qml/MyItem.qml 0
171 \li \snippet qml/qtbinding/functions-qml/main.cpp 0
174 Notice the Q_RETURN_ARG() and Q_ARG() arguments for QMetaObject::invokeMethod() must be specified as
175 QVariant types, as this is the generic data type used for QML functions and return values.
177 To call a C++ function from QML, the function must be either a Qt slot, or a function marked with
178 the Q_INVOKABLE macro, to be available to QML. In the following example, the QML code invokes
179 methods on the \c myObject object, which has been set using QQmlContext::setContextProperty():
184 \snippet qml/qtbinding/functions-cpp/MyItem.qml 0
186 \snippet qml/qtbinding/functions-cpp/myclass.h 0
188 \snippet qml/qtbinding/functions-cpp/main.cpp 0
191 QML supports the calling of overloaded C++ functions. If there are multiple C++ functions with the
192 same name but different arguments, the correct function will be called according to the number and
193 the types of arguments that are provided.
195 \section1 Signals and Slots
197 All QML signals are automatically available to C++, and can be connected to using QObject::connect()
198 like any ordinary Qt C++ signal. In return, any C++ signal can be received by a QML object using
199 \l {Signal Handlers}{signal handlers}.
201 Here is a QML component with a signal named \c qmlSignal. This signal is connected to a C++ object's
202 slot using QObject::connect(), so that the \c cppSlot() method is called whenever the \c qmlSignal
208 \snippet qml/qtbinding/signals-qml/MyItem.qml 0
210 \snippet qml/qtbinding/signals-qml/myclass.h 0
212 \snippet qml/qtbinding/signals-qml/main.cpp 0
215 To connect to Qt C++ signals from within QML, use a signal handler with the \c on<SignalName> syntax.
216 In the following example, the
217 QML code creates a \c ImageViewer object, and the \c imageChanged and \c loadingError signals of the
218 C++ object are connected to through \c onImagedChanged and \c onLoadingError signal handlers in QML:
224 \snippet qml/qtbinding/signals-cpp/imageviewer.h start
226 \snippet qml/qtbinding/signals-cpp/imageviewer.h end
229 \snippet qml/qtbinding/signals-cpp/standalone.qml 0
232 (Note that if a signal has been declared as the NOTIFY signal for a property, QML allows it to be
233 received with an \c on<Property>Changed handler even if the signal's name does not follow the \c
234 <Property>Changed naming convention. In the above example, if the "imageChanged" signal was named
235 "imageModified" instead, the \c onImageChanged signal handler would still be called.)
237 If, however, the object with the signal is not created from within the QML code, and the QML item only has a
238 reference to the created object - for example, if the object was set using
239 QQmlContext::setContextProperty() - then the \l Connections element can be used
240 instead to create the signal handler:
244 \li \snippet qml/qtbinding/signals-cpp/main.cpp connections
245 \li \snippet qml/qtbinding/signals-cpp/MyItem.qml 0
248 C++ signals can use enum values as parameters provided that the enum is declared in the
249 class that is emitting the signal, and that the enum is registered using Q_ENUMS.
250 See \l {Using enumerations of a custom type} below for details.