/usr/share/qt5/doc/qtqml/qtqml-cppintegration-interactqmlfromcpp.html is in qtdeclarative5-doc-html 5.5.1-2ubuntu6.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- interactqmlfromcpp.qdoc -->
<title>Interacting with QML Objects from C++ | Qt QML 5.5</title>
<link rel="stylesheet" type="text/css" href="style/offline.css" />
</head>
<body>
<div class="header" id="qtdocheader">
<div class="main">
<div class="main-rounded">
<div class="navigationbar">
<ul>
<li>Qt 5.5</li>
<li><a href="qtqml-index.html">Qt QML</a></li>
<li>Interacting with QML Objects from C++</li>
<li id="buildversion">Qt 5.5.1 Reference Documentation</li>
</ul>
</div>
</div>
<div class="content">
<div class="line">
<div class="content mainContent">
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#loading-qml-objects-from-c">Loading QML Objects from C++</a></li>
<li class="level1"><a href="#accessing-loaded-qml-objects-by-object-name">Accessing Loaded QML Objects by Object Name</a></li>
<li class="level1"><a href="#accessing-members-of-a-qml-object-type-from-c">Accessing Members of a QML Object Type from C++</a></li>
<li class="level2"><a href="#properties">Properties</a></li>
<li class="level2"><a href="#invoking-qml-methods">Invoking QML Methods</a></li>
<li class="level2"><a href="#connecting-to-qml-signals">Connecting to QML Signals</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Interacting with QML Objects from C++</h1>
<span class="subtitle"></span>
<!-- $$$qtqml-cppintegration-interactqmlfromcpp.html-description -->
<div class="descr"> <a name="details"></a>
<p>All QML object types are QObject-derived types, whether they are internally implemented by the engine or <a href="qtqml-cppintegration-definetypes.html">defined by third-party sources</a>. This means the QML engine can use the Qt Meta Object System to dynamically instantiate any QML object type and inspect the created objects.</p>
<p>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.</p>
<a name="loading-qml-objects-from-c"></a>
<h2 id="loading-qml-objects-from-c">Loading QML Objects from C++</h2>
<p>A QML document can be loaded with <a href="qqmlcomponent.html">QQmlComponent</a> or QQuickView. <a href="qqmlcomponent.html">QQmlComponent</a> 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.</p>
<p>For example, suppose there is a <code>MyItem.qml</code> file that looks like this:</p>
<pre class="qml">import QtQuick 2.0
<span class="type">Item</span> {
<span class="name">width</span>: <span class="number">100</span>; <span class="name">height</span>: <span class="number">100</span>
}</pre>
<p>This QML document can be loaded with <a href="qqmlcomponent.html">QQmlComponent</a> or QQuickView with the following C++ code. Using a <a href="qqmlcomponent.html">QQmlComponent</a> requires calling <a href="qqmlcomponent.html#create">QQmlComponent::create</a>() to create a new instance of the component, while a QQuickView automatically creates an instance of the component, which is accessible via QQuickView::rootObject():</p>
<div class="table"><table class="generic">
<tr valign="top" class="odd"><td ><pre class="cpp"><span class="comment">// Using QQmlComponent</span>
<span class="type"><a href="qqmlengine.html">QQmlEngine</a></span> engine;
<span class="type"><a href="qqmlcomponent.html">QQmlComponent</a></span> component(<span class="operator">&</span>engine<span class="operator">,</span>
<span class="type">QUrl</span><span class="operator">::</span>fromLocalFile(<span class="string">"MyItem.qml"</span>));
<span class="type">QObject</span> <span class="operator">*</span>object <span class="operator">=</span> component<span class="operator">.</span>create();
...
<span class="keyword">delete</span> object;</pre>
</td><td ><pre class="cpp"><span class="comment">// Using QQuickView</span>
<span class="type">QQuickView</span> view;
view<span class="operator">.</span>setSource(<span class="type">QUrl</span><span class="operator">::</span>fromLocalFile(<span class="string">"MyItem.qml"</span>));
view<span class="operator">.</span>show();
<span class="type">QObject</span> <span class="operator">*</span>object <span class="operator">=</span> view<span class="operator">.</span>rootObject();</pre>
</td></tr>
</table></div>
<p>This <code>object</code> is the instance of the <code>MyItem.qml</code> component that has been created. You can now modify the item's properties using QObject::setProperty() or <a href="qqmlproperty.html">QQmlProperty</a>:</p>
<pre class="cpp">object<span class="operator">-</span><span class="operator">></span>setProperty(<span class="string">"width"</span><span class="operator">,</span> <span class="number">500</span>);
<span class="type"><a href="qqmlproperty.html">QQmlProperty</a></span>(object<span class="operator">,</span> <span class="string">"width"</span>)<span class="operator">.</span>write(<span class="number">500</span>);</pre>
<p>Alternatively, you can cast the object to its actual type and call methods with compile-time safety. In this case the base object of <code>MyItem.qml</code> is an Item, which is defined by the QQuickItem class:</p>
<pre class="cpp"><span class="type">QQuickItem</span> <span class="operator">*</span>item <span class="operator">=</span> qobject_cast<span class="operator"><</span><span class="type">QQuickItem</span><span class="operator">*</span><span class="operator">></span>(object);
item<span class="operator">-</span><span class="operator">></span>setWidth(<span class="number">500</span>);</pre>
<p>You can also connect to any signals or call methods defined in the component using QMetaObject::invokeMethod() and QObject::connect(). See <a href="qtqml-cppintegration-interactqmlfromcpp.html#invoking-qml-methods">Invoking QML Methods</a> and <a href="qtqml-cppintegration-interactqmlfromcpp.html#connecting-to-qml-signals">Connecting to QML Signals</a> below for further details.</p>
<a name="accessing-loaded-qml-objects-by-object-name"></a>
<h2 id="accessing-loaded-qml-objects-by-object-name">Accessing Loaded QML Objects by Object Name</h2>
<p>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 <code>MyItem.qml</code> had a child Rectangle item:</p>
<pre class="qml">import QtQuick 2.0
<span class="type">Item</span> {
<span class="name">width</span>: <span class="number">100</span>; <span class="name">height</span>: <span class="number">100</span>
<span class="type">Rectangle</span> {
<span class="name">anchors</span>.fill: <span class="name">parent</span>
<span class="name">objectName</span>: <span class="string">"rect"</span>
}
}</pre>
<p>The child could be located like this:</p>
<pre class="cpp"><span class="type">QObject</span> <span class="operator">*</span>rect <span class="operator">=</span> object<span class="operator">-</span><span class="operator">></span>findChild<span class="operator"><</span><span class="type">QObject</span><span class="operator">*</span><span class="operator">></span>(<span class="string">"rect"</span>);
<span class="keyword">if</span> (rect)
rect<span class="operator">-</span><span class="operator">></span>setProperty(<span class="string">"color"</span><span class="operator">,</span> <span class="string">"red"</span>);</pre>
<p>Note that an object may have multiple children with the same <code>objectName</code>. For example, ListView creates multiple instances of its delegate, so if its delegate is declared with a particular objectName, the ListView will have multiple children with the same <code>objectName</code>. In this case, QObject::findChildren() can be used to find all children with a matching <code>objectName</code>.</p>
<p><b>Warning:</b> 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 <code>objectName</code>. 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.</p>
<a name="accessing-members-of-a-qml-object-type-from-c"></a>
<h2 id="accessing-members-of-a-qml-object-type-from-c">Accessing Members of a QML Object Type from C++</h2>
<a name="properties"></a>
<h3 >Properties</h3>
<p>Any properties declared in a QML object are automatically accessible from C++. Given a QML item like this:</p>
<pre class="qml"><span class="comment">// MyItem.qml</span>
import QtQuick 2.0
<span class="type">Item</span> {
property <span class="type">int</span> <span class="name">someNumber</span>: <span class="number">100</span>
}</pre>
<p>The value of the <code>someNumber</code> property can be set and read using <a href="qqmlproperty.html">QQmlProperty</a>, or QObject::setProperty() and QObject::property():</p>
<pre class="cpp"><span class="type"><a href="qqmlengine.html">QQmlEngine</a></span> engine;
<span class="type"><a href="qqmlcomponent.html">QQmlComponent</a></span> component(<span class="operator">&</span>engine<span class="operator">,</span> <span class="string">"MyItem.qml"</span>);
<span class="type">QObject</span> <span class="operator">*</span>object <span class="operator">=</span> component<span class="operator">.</span>create();
qDebug() <span class="operator"><</span><span class="operator"><</span> <span class="string">"Property value:"</span> <span class="operator"><</span><span class="operator"><</span> <span class="type"><a href="qqmlproperty.html">QQmlProperty</a></span><span class="operator">::</span>read(object<span class="operator">,</span> <span class="string">"someNumber"</span>)<span class="operator">.</span>toInt();
<span class="type"><a href="qqmlproperty.html">QQmlProperty</a></span><span class="operator">::</span>write(object<span class="operator">,</span> <span class="string">"someNumber"</span><span class="operator">,</span> <span class="number">5000</span>);
qDebug() <span class="operator"><</span><span class="operator"><</span> <span class="string">"Property value:"</span> <span class="operator"><</span><span class="operator"><</span> object<span class="operator">-</span><span class="operator">></span>property(<span class="string">"someNumber"</span>)<span class="operator">.</span>toInt();
object<span class="operator">-</span><span class="operator">></span>setProperty(<span class="string">"someNumber"</span><span class="operator">,</span> <span class="number">100</span>);</pre>
<p>You should always use QObject::setProperty(), <a href="qqmlproperty.html">QQmlProperty</a> 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 type <code>PushButton</code> with a <code>buttonText</code> property that internally reflects the value of a <code>m_buttonText</code> member variable. Modifying the member variable directly like this is not a good idea:</p>
<pre class="cpp"><span class="comment">//bad code</span>
<span class="type"><a href="qqmlcomponent.html">QQmlComponent</a></span> component(engine<span class="operator">,</span> <span class="string">"MyButton.qml"</span>);
PushButton <span class="operator">*</span>button <span class="operator">=</span> qobject_cast<span class="operator"><</span>PushButton<span class="operator">*</span><span class="operator">></span>(component<span class="operator">.</span>create());
button<span class="operator">-</span><span class="operator">></span>m_buttonText <span class="operator">=</span> <span class="string">"Click me"</span>;</pre>
<p>Since the value is changed directly, this bypasses Qt's meta-object system and the QML engine is not made aware of the property change. This means property bindings to <code>buttonText</code> would not be updated, and any <code>onButtonTextChanged</code> handlers would not be called.</p>
<a name="invoking-qml-methods"></a>
<h3 >Invoking QML Methods</h3>
<p>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++.</p>
<p>Here is a C++ application that calls a QML method using QMetaObject::invokeMethod():</p>
<div class="table"><table class="generic">
<tr valign="top" class="odd"><td >QML</td><td ><pre class="qml"><span class="comment">// MyItem.qml</span>
import QtQuick 2.0
<span class="type">Item</span> {
<span class="keyword">function</span> <span class="name">myQmlFunction</span>(<span class="name">msg</span>) {
<span class="name">console</span>.<span class="name">log</span>(<span class="string">"Got message:"</span>, <span class="name">msg</span>)
<span class="keyword">return</span> <span class="string">"some return value"</span>
}
}</pre>
</td></tr>
<tr valign="top" class="even"><td >C++</td><td ><pre class="cpp"><span class="comment">// main.cpp</span>
<span class="type"><a href="qqmlengine.html">QQmlEngine</a></span> engine;
<span class="type"><a href="qqmlcomponent.html">QQmlComponent</a></span> component(<span class="operator">&</span>engine<span class="operator">,</span> <span class="string">"MyItem.qml"</span>);
<span class="type">QObject</span> <span class="operator">*</span>object <span class="operator">=</span> component<span class="operator">.</span>create();
<span class="type">QVariant</span> returnedValue;
<span class="type">QVariant</span> msg <span class="operator">=</span> <span class="string">"Hello from C++"</span>;
<span class="type">QMetaObject</span><span class="operator">::</span>invokeMethod(object<span class="operator">,</span> <span class="string">"myQmlFunction"</span><span class="operator">,</span>
Q_RETURN_ARG(<span class="type">QVariant</span><span class="operator">,</span> returnedValue)<span class="operator">,</span>
Q_ARG(<span class="type">QVariant</span><span class="operator">,</span> msg));
qDebug() <span class="operator"><</span><span class="operator"><</span> <span class="string">"QML function returned:"</span> <span class="operator"><</span><span class="operator"><</span> returnedValue<span class="operator">.</span>toString();
<span class="keyword">delete</span> object;</pre>
</td></tr>
</table></div>
<p>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.</p>
<a name="connecting-to-qml-signals"></a>
<h3 >Connecting to QML Signals</h3>
<p>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 <a href="qtqml-syntax-signals.html">signal handlers</a>.</p>
<p>Here is a QML component with a signal named <code>qmlSignal</code> that is emitted with a string-type parameter. This signal is connected to a C++ object's slot using QObject::connect(), so that the <code>cppSlot()</code> method is called whenever the <code>qmlSignal</code> is emitted:</p>
<div class="table"><table class="generic">
<tr valign="top" class="odd"><td ><pre class="qml"><span class="comment">// MyItem.qml</span>
import QtQuick 2.0
<span class="type">Item</span> {
<span class="name">id</span>: <span class="name">item</span>
<span class="name">width</span>: <span class="number">100</span>; <span class="name">height</span>: <span class="number">100</span>
signal <span class="type">qmlSignal</span>(string msg)
<span class="type">MouseArea</span> {
<span class="name">anchors</span>.fill: <span class="name">parent</span>
<span class="name">onClicked</span>: <span class="name">item</span>.<span class="name">qmlSignal</span>(<span class="string">"Hello from QML"</span>)
}
}</pre>
</td></tr>
<tr valign="top" class="even"><td ><pre class="cpp"><span class="keyword">class</span> MyClass : <span class="keyword">public</span> <span class="type">QObject</span>
{
Q_OBJECT
<span class="keyword">public</span> <span class="keyword">slots</span>:
<span class="type">void</span> cppSlot(<span class="keyword">const</span> <span class="type">QString</span> <span class="operator">&</span>msg) {
qDebug() <span class="operator"><</span><span class="operator"><</span> <span class="string">"Called the C++ slot with message:"</span> <span class="operator"><</span><span class="operator"><</span> msg;
}
};
<span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span>argv<span class="operator">[</span><span class="operator">]</span>) {
<span class="type">QGuiApplication</span> app(argc<span class="operator">,</span> argv);
<span class="type">QQuickView</span> view(<span class="type">QUrl</span><span class="operator">::</span>fromLocalFile(<span class="string">"MyItem.qml"</span>));
<span class="type">QObject</span> <span class="operator">*</span>item <span class="operator">=</span> view<span class="operator">.</span>rootObject();
MyClass myClass;
<span class="type">QObject</span><span class="operator">::</span>connect(item<span class="operator">,</span> SIGNAL(qmlSignal(<span class="type">QString</span>))<span class="operator">,</span>
<span class="operator">&</span>myClass<span class="operator">,</span> SLOT(cppSlot(<span class="type">QString</span>)));
view<span class="operator">.</span>show();
<span class="keyword">return</span> app<span class="operator">.</span>exec();
}</pre>
</td></tr>
</table></div>
<p>When a QML object type is used as a signal parameter, the parameter should use <a href="qml-var.html">var</a> as the type, and the value should be received in C++ using the QVariant type:</p>
<div class="table"><table class="generic">
<tr valign="top" class="odd"><td ><pre class="qml"> <span class="comment">// MyItem.qml</span>
import QtQuick 2.0
<span class="type">Item</span> {
<span class="name">id</span>: <span class="name">item</span>
<span class="name">width</span>: <span class="number">100</span>; <span class="name">height</span>: <span class="number">100</span>
signal <span class="type">qmlSignal</span>(var anObject)
<span class="type">MouseArea</span> {
<span class="name">anchors</span>.fill: <span class="name">parent</span>
<span class="name">onClicked</span>: <span class="name">item</span>.<span class="name">qmlSignal</span>(<span class="name">item</span>)
}
}</pre>
</td><td ><pre class="cpp"> <span class="keyword">class</span> MyClass : <span class="keyword">public</span> <span class="type">QObject</span>
{
Q_OBJECT
<span class="keyword">public</span> <span class="keyword">slots</span>:
<span class="type">void</span> cppSlot(<span class="keyword">const</span> <span class="type">QVariant</span> <span class="operator">&</span>v) {
qDebug() <span class="operator"><</span><span class="operator"><</span> <span class="string">"Called the C++ slot with value:"</span> <span class="operator"><</span><span class="operator"><</span> v;
<span class="type">QQuickItem</span> <span class="operator">*</span>item <span class="operator">=</span>
qobject_cast<span class="operator"><</span><span class="type">QQuickItem</span><span class="operator">*</span><span class="operator">></span>(v<span class="operator">.</span>value<span class="operator"><</span><span class="type">QObject</span><span class="operator">*</span><span class="operator">></span>());
qDebug() <span class="operator"><</span><span class="operator"><</span> <span class="string">"Item dimensions:"</span> <span class="operator"><</span><span class="operator"><</span> item<span class="operator">-</span><span class="operator">></span>width()
<span class="operator"><</span><span class="operator"><</span> item<span class="operator">-</span><span class="operator">></span>height();
}
};
<span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span>argv<span class="operator">[</span><span class="operator">]</span>) {
<span class="type">QApplication</span> app(argc<span class="operator">,</span> argv);
<span class="type">QQuickView</span> view(<span class="type">QUrl</span><span class="operator">::</span>fromLocalFile(<span class="string">"MyItem.qml"</span>));
<span class="type">QObject</span> <span class="operator">*</span>item <span class="operator">=</span> view<span class="operator">.</span>rootObject();
MyClass myClass;
<span class="type">QObject</span><span class="operator">::</span>connect(item<span class="operator">,</span> SIGNAL(qmlSignal(<span class="type">QVariant</span>))<span class="operator">,</span>
<span class="operator">&</span>myClass<span class="operator">,</span> SLOT(cppSlot(<span class="type">QVariant</span>)));
view<span class="operator">.</span>show();
<span class="keyword">return</span> app<span class="operator">.</span>exec();
}</pre>
</td></tr>
</table></div>
</div>
<!-- @@@qtqml-cppintegration-interactqmlfromcpp.html -->
</div>
</div>
</div>
</div>
</div>
<div class="footer">
<p>
<acronym title="Copyright">©</acronym> 2015 The Qt Company Ltd.
Documentation contributions included herein are the copyrights of
their respective owners.<br> The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation.<br> Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property
of their respective owners. </p>
</div>
</body>
</html>
|