DataSharingQML2CPP: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
=Sharing Data Between <span class="caps">QML</span> Documents and C++ Objects=
[[Category:Developing_with_Qt::Qt Quick]]<br />[toc align_right=&quot;yes&amp;quot; depth=&quot;2&amp;quot;]


Qt Quick is now officially released with Qt 4.7. Here’s a look at available techniques for sharing data between <span class="caps">QML</span> documents and C++ objects. In general, exposing a QObject will make all of its signals, slots and properties available to the <span class="caps">QML</span> environment.
= Sharing Data Between QML Documents and C++ Objects =


==Sharing values==
Qt Quick is now officially released with Qt 4.7. Here's a look at available techniques for sharing data between QML documents and C++ objects. In general, exposing a QObject will make all of its signals, slots and properties available to the QML environment.


All <span class="caps">QML</span> code executes within a context. The context keeps track of what data is available to different leaves and nodes in a <span class="caps">QML</span> object tree. Data is shared as context properties or context objects. A context property is simply a way to expose a given QObject through a given name. For example, to expose a QColor property named frameColor to <span class="caps">QML</span>, simply use the following snippet:
== Sharing values ==


This property can then be accessed from within the <span class="caps">QML</span> context as a global property, as shown below. Remember property values are bound, not assigned, in <span class="caps">QML</span>. This means you can alter the frameColor property from C++ and the change will be reflected in <span class="caps">QML</span>.
All QML code executes within a context. The context keeps track of what data is available to different leaves and nodes in a QML object tree. Data is shared as context properties or context objects. A context property is simply a way to expose a given QObject through a given name. For example, to expose a QColor property named frameColor to QML, simply use the following snippet:
 
<code>QDeclarativeContext *context = …;<br />context-&gt;setContextProperty(&quot;frameColor&amp;quot;, QColor(Qt::red));<br /></code>
 
This property can then be accessed from within the QML context as a global property, as shown below. Remember property values are bound, not assigned, in QML. This means you can alter the frameColor property from C++ and the change will be reflected in QML.
 
<code>Rectangle {<br /> border.color: frameColor<br />}<br /></code>


It is possible to add multiple context properties to a QDeclarativeContext object, but as the list of properties climbs the readability of the code crumbles. Instead of setting each property individually, it is cleaner to gather all context properties into one QObject and set the single object as the context object instead.
It is possible to add multiple context properties to a QDeclarativeContext object, but as the list of properties climbs the readability of the code crumbles. Instead of setting each property individually, it is cleaner to gather all context properties into one QObject and set the single object as the context object instead.
Line 15: Line 21:
Note that all properties added explicitly by QDeclarativeContext::setContextProperty() [doc.qt.nokia.com] take precedence over the context object’s default properties.
Note that all properties added explicitly by QDeclarativeContext::setContextProperty() [doc.qt.nokia.com] take precedence over the context object’s default properties.


==<span class="caps">QML</span> views into C++ models==
<code>class MyInterface : … {<br /> …<br /> Q_PROPERTY(QAbstractItemModel *myModel READ model NOTIFY modelChanged)<br /> …<br /> };
 
MyInterface *myInterface = new MyInterface;<br /> QDeclarativeEngine engine;<br /> QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext());<br /> context-&gt;setContextObject(myInterface);
 
QDeclarativeComponent component(&amp;engine, &quot;ListView { model=myModel }&quot;);<br /> component.create(context);<br /></code>
 
== QML views into C++ models ==
 
Object properties work well when providing a limited set of values to QML, but are difficult to manage when large data sets are involved. In these cases formal models are visualized with formal views.


Object properties work well when providing a limited set of values to <span class="caps">QML</span>, but are difficult to manage when large data sets are involved. In these cases formal models are visualized with formal views.
Qt widgets can create views into models that are exposed using the QAbstractItemModel interface. This interface is also supported by QML.


Qt widgets can create views into models that are exposed using the QAbstractItemModel interface. This interface is also supported by <span class="caps">QML</span>.
To expose a QAbstractItemModel to QML a context property is used:


To expose a QAbstractItemModel to <span class="caps">QML</span> a context property is used:
<code>QAbstractItemModel *model = …;<br />context-&gt;setContextProperty(&quot;dataModel&amp;quot;, model);<br /></code>


<span class="caps">QML</span> currently provides three elements devoted to creating views into models. The ListView and GridView elements create list and grid views respectively. The PathView element lays out model-provided items on a path, for example a loop path that allows you to create a carousel interface into a list.
QML currently provides three elements devoted to creating views into models. The ListView and GridView elements create list and grid views respectively. The PathView element lays out model-provided items on a path, for example a loop path that allows you to create a carousel interface into a list.


Regardless of the view element employed, the context property set to the data model is bound to the model property of a view element.
Regardless of the view element employed, the context property set to the data model is bound to the model property of a view element.


The actual visualization of each item of the model is handled through components. The highlight and delegate components are instantiated and can use model data when binding properties. The names used to refer to the different roles of the model are set using the QAbstractItemModel::setRoleNames method, which will make them accessible to <span class="caps">QML</span>.
<code>ListView {<br /> model: contactModel<br /> delegate: delegate<br /> highlight: highlight<br />}<br /></code>
 
The actual visualization of each item of the model is handled through components. The highlight and delegate components are instantiated and can use model data when binding properties. The names used to refer to the different roles of the model are set using the QAbstractItemModel::setRoleNames method, which will make them accessible to QML.
 
<code>Component {<br /> id: delegate
 
Item {<br /> width: 100; height: 40
 
Row {<br /> x: 5; y: 5; spacing: 5
 
Rectangle {<br /> width: 30; height: 30<br /> border.width: 2; border.color: &quot;black&amp;quot;<br /> color: decoration<br /> }<br /> Text {<br /> x: 5; y: 10<br /> text: display<br /> }<br /> }<br /> }<br />}<br /></code>


==Build models in <span class="caps">QML</span>==
== Build models in QML ==


You can also build models directly in <span class="caps">QML</span> using ListModel or XMLListModel. For example, let’s use ListModel and PathView to the a view like the following rotating carousel. (see also the [http://doc.trolltech.com/4.7-snapshot/qml-pathview.html PathView] ''[doc.trolltech.com]'' documentation.)
You can also build models directly in QML using ListModel or XMLListModel. For example, let’s use ListModel and PathView to the a view like the following rotating carousel. (see also the &quot;PathView &quot;:http://doc.trolltech.com/4.7-snapshot/qml-pathview.html documentation.)


http://doc.trolltech.com/4.7-snapshot/images/pathview.gif ''[doc.trolltech.com]'' (Carousel view)
&quot;http://doc.trolltech.com/4.7-snapshot/images/pathview.gif(Carousel view)&quot;:http://doc.trolltech.com/4.7-snapshot/images/pathview.gif (Carousel view)


Start by creating a list model:
Start by creating a list model:
<code> import Qt 4.7
ListModel {<br /> ListElement {<br /> name: &quot;Bill Jones&amp;quot;<br /> icon: &quot;pics/qtlogo.png&amp;quot;<br /> }<br /> ListElement {<br /> name: &quot;Jane Doe&amp;quot;<br /> icon: &quot;pics/qtlogo.png&amp;quot;<br /> }<br /> ListElement {<br /> name: &quot;John Smith&amp;quot;<br /> icon: &quot;pics/qtlogo.png&amp;quot;<br /> }<br /> }<br /></code>


Save the model in the file ContactModel.qml and represent it as rotating carousel using:
Save the model in the file ContactModel.qml and represent it as rotating carousel using:


===Categories:===
<code> import Qt 4.7
 
Rectangle {<br /> width: 240; height: 200
 
Component {<br /> id: delegateItem<br /> Column {<br /> Image { anchors.horizontalCenter:<br /> name.horizontalCenter;<br /> width: 64; height: 64;<br /> source: icon<br /> }<br /> Text { text: name; font.pointSize: 16 }<br /> }<br /> }


* [[:Category:Developing with Qt|Developing_with_Qt]]
PathView {<br /> anchors.fill: parent<br /> model: ContactModel {}<br /> delegate: delegateItem<br /> path: Path {<br /> startX: 120; startY: 100<br /> PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }<br /> PathQuad { x: 120; y: 100; controlX: –20; controlY: 75 }<br /> }<br /> }<br /> }<br /></code>
** [[:Category:Developing with Qt::Qt-Quick|Qt Quick]]

Revision as of 09:44, 24 February 2015


[toc align_right="yes&quot; depth="2&quot;]

Sharing Data Between QML Documents and C++ Objects

Qt Quick is now officially released with Qt 4.7. Here's a look at available techniques for sharing data between QML documents and C++ objects. In general, exposing a QObject will make all of its signals, slots and properties available to the QML environment.

Sharing values

All QML code executes within a context. The context keeps track of what data is available to different leaves and nodes in a QML object tree. Data is shared as context properties or context objects. A context property is simply a way to expose a given QObject through a given name. For example, to expose a QColor property named frameColor to QML, simply use the following snippet:

QDeclarativeContext *context = ;<br />context-&gt;setContextProperty(&quot;frameColor&amp;quot;, QColor(Qt::red));<br />

This property can then be accessed from within the QML context as a global property, as shown below. Remember property values are bound, not assigned, in QML. This means you can alter the frameColor property from C++ and the change will be reflected in QML.

Rectangle {<br /> border.color: frameColor<br />}<br />

It is possible to add multiple context properties to a QDeclarativeContext object, but as the list of properties climbs the readability of the code crumbles. Instead of setting each property individually, it is cleaner to gather all context properties into one QObject and set the single object as the context object instead.

The next snippet defines the interface object MyInterface using the setContextProperty method. The Q_PROPERTY macro defines the properties available within MyInterface to the Qt property system and sets notification signals, allowing subsequent bindings to work.

Note that all properties added explicitly by QDeclarativeContext::setContextProperty() [doc.qt.nokia.com] take precedence over the context object’s default properties.

class MyInterface :  {<br /> <br /> Q_PROPERTY(QAbstractItemModel *myModel READ model NOTIFY modelChanged)<br /> <br /> };

MyInterface *myInterface = new MyInterface;<br /> QDeclarativeEngine engine;<br /> QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext());<br /> context-&gt;setContextObject(myInterface);

QDeclarativeComponent component(&amp;engine, &quot;ListView { model=myModel }&quot;);<br /> component.create(context);<br />

QML views into C++ models

Object properties work well when providing a limited set of values to QML, but are difficult to manage when large data sets are involved. In these cases formal models are visualized with formal views.

Qt widgets can create views into models that are exposed using the QAbstractItemModel interface. This interface is also supported by QML.

To expose a QAbstractItemModel to QML a context property is used:

QAbstractItemModel *model = ;<br />context-&gt;setContextProperty(&quot;dataModel&amp;quot;, model);<br />

QML currently provides three elements devoted to creating views into models. The ListView and GridView elements create list and grid views respectively. The PathView element lays out model-provided items on a path, for example a loop path that allows you to create a carousel interface into a list.

Regardless of the view element employed, the context property set to the data model is bound to the model property of a view element.

ListView {<br /> model: contactModel<br /> delegate: delegate<br /> highlight: highlight<br />}<br />

The actual visualization of each item of the model is handled through components. The highlight and delegate components are instantiated and can use model data when binding properties. The names used to refer to the different roles of the model are set using the QAbstractItemModel::setRoleNames method, which will make them accessible to QML.

Component {<br /> id: delegate

Item {<br /> width: 100; height: 40

Row {<br /> x: 5; y: 5; spacing: 5

Rectangle {<br /> width: 30; height: 30<br /> border.width: 2; border.color: &quot;black&amp;quot;<br /> color: decoration<br /> }<br /> Text {<br /> x: 5; y: 10<br /> text: display<br /> }<br /> }<br /> }<br />}<br />

Build models in QML

You can also build models directly in QML using ListModel or XMLListModel. For example, let’s use ListModel and PathView to the a view like the following rotating carousel. (see also the "PathView ":http://doc.trolltech.com/4.7-snapshot/qml-pathview.html documentation.)

"http://doc.trolltech.com/4.7-snapshot/images/pathview.gif(Carousel view)":pathview.gif (Carousel view)

Start by creating a list model:

 import Qt 4.7

ListModel {<br /> ListElement {<br /> name: &quot;Bill Jones&amp;quot;<br /> icon: &quot;pics/qtlogo.png&amp;quot;<br /> }<br /> ListElement {<br /> name: &quot;Jane Doe&amp;quot;<br /> icon: &quot;pics/qtlogo.png&amp;quot;<br /> }<br /> ListElement {<br /> name: &quot;John Smith&amp;quot;<br /> icon: &quot;pics/qtlogo.png&amp;quot;<br /> }<br /> }<br />

Save the model in the file ContactModel.qml and represent it as rotating carousel using:

 import Qt 4.7

Rectangle {<br /> width: 240; height: 200

Component {<br /> id: delegateItem<br /> Column {<br /> Image { anchors.horizontalCenter:<br /> name.horizontalCenter;<br /> width: 64; height: 64;<br /> source: icon<br /> }<br /> Text { text: name; font.pointSize: 16 }<br /> }<br /> }

PathView {<br /> anchors.fill: parent<br /> model: ContactModel {}<br /> delegate: delegateItem<br /> path: Path {<br /> startX: 120; startY: 100<br /> PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }<br /> PathQuad { x: 120; y: 100; controlX: 20; controlY: 75 }<br /> }<br /> }<br /> }<br />