How to expose lists to QML: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
[[Category:HowTo]]<br />[[Category:Developing_with_Qt::General]]<br />[[Category:Tutorial]]<br />[toc align_right=&quot;yes&amp;quot; depth=&quot;2&amp;quot;]
[[Category:HowTo]]
[[Category:Developing_with_Qt::General]]
[[Category:Tutorial]]
[toc align_right="yes" depth="2"]


'''English''' [[How_to_expose_lists_to_QML_Greek|Ελληνικά]]
'''English''' [[How_to_expose_lists_to_QML_Greek|Ελληνικά]]
Line 7: Line 10:
== Which class to use? ==
== Which class to use? ==


&quot;QDeclarativeListProperty&amp;quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html allows you to expose list like properties to QML. When implementing the function pointers in this class, memory management will be taken care of for you and the bindings will work correctly as well. Using a standard &quot;QList &quot;:http://doc.qt.nokia.com/latest/qlist.html instead of QDeclarativeListProperty, will not take care of memory management and can cause your application to leak. In addition QList does not provide notification signals when children change. So when simply using a QList, the bindings won't work properly either. QDeclarativeListProperty is hence the recommended class to use for lists in QML.
"QDeclarativeListProperty":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html allows you to expose list like properties to QML. When implementing the function pointers in this class, memory management will be taken care of for you and the bindings will work correctly as well. Using a standard "QList ":http://doc.qt.nokia.com/latest/qlist.html instead of QDeclarativeListProperty, will not take care of memory management and can cause your application to leak. In addition QList does not provide notification signals when children change. So when simply using a QList, the bindings won't work properly either. QDeclarativeListProperty is hence the recommended class to use for lists in QML.


== Which constructor to use? ==
== Which constructor to use? ==


QDeclarativeListProperty provides 2 constructors. The &quot;first one&amp;quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty taking a QList is there for convenience and should only be used for prototyping since it does not clean up memory for you. It still connects up the bindings properly and is therefore recommended over using a simple QList.
QDeclarativeListProperty provides 2 constructors. The "first one":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty taking a QList is there for convenience and should only be used for prototyping since it does not clean up memory for you. It still connects up the bindings properly and is therefore recommended over using a simple QList.


The second &quot;QDeclarativeListProperty constructor&amp;quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty-3 constructs a QDeclarativeListProperty from a set of operation functions. It works by passing functions to be called when appending, clearing, counting and getting the current position, but only the append function is necessary to implement. This is the constructor you should use in production code.
The second "QDeclarativeListProperty constructor":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty-3 constructs a QDeclarativeListProperty from a set of operation functions. It works by passing functions to be called when appending, clearing, counting and getting the current position, but only the append function is necessary to implement. This is the constructor you should use in production code.


== Example on how to use QDeclarativeListProperty ==
== Example on how to use QDeclarativeListProperty ==


The following example shows how the &quot;QDeclarativeListProperty::AppendFunction&amp;quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#AppendFunction-typedef and &quot;QDeclarativeListProperty::ClearFunction &quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#ClearFunction-typedef can be implemented:
The following example shows how the "QDeclarativeListProperty::AppendFunction":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#AppendFunction-typedef and "QDeclarativeListProperty::ClearFunction ":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#ClearFunction-typedef can be implemented:


<code><br />#include &lt;QtGui&amp;gt;<br />#include &lt;QtDeclarative&amp;gt;
<code>
#include <QtGui>
#include <QtDeclarative>


class MyObject : public QObject<br />{<br /> Q_OBJECT<br /> Q_PROPERTY(QDeclarativeListProperty&amp;lt;MyObject&amp;gt; getInfo READ getInfo CONSTANT)<br />public:<br /> MyObject()<br /> {}
class MyObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QDeclarativeListProperty<MyObject> getInfo READ getInfo CONSTANT)
public:
MyObject()
{}


~MyObject()<br /> {}<br /> QDeclarativeListProperty&amp;lt;MyObject&amp;gt; getInfo()<br /> {<br /> for (int i = 0; i &lt; 10; +''i)<br /> {<br /> list &lt;&lt; new MyObject();<br /> }<br /> return QDeclarativeListProperty&amp;lt;MyObject&amp;gt;(this, 0, &amp;MyObject::appendObject, 0, 0, &amp;MyObject::clearObject);<br /> }<br /> static void appendObject(QDeclarativeListProperty&amp;lt;MyObject&amp;gt; *l, MyObject *obj)<br /> {<br /> MyObject '''object = qobject_cast&amp;lt;MyObject'''&gt;(l-&gt;object);<br /> if (object)<br /> object-&gt;list &lt;&lt; obj;<br /> }<br /> static void clearObject(QDeclarativeListProperty&amp;lt;MyObject&amp;gt; *l)<br /> {<br /> MyObject '''object = qobject_cast&amp;lt;MyObject'''&gt;(l-&gt;object);<br /> if (object) {<br /> foreach (MyObject '''o, object-&gt;list)<br /> delete o;<br /> object-&gt;list.clear();<br /> }<br /> }<br /> QList&amp;lt;MyObject'''&gt; list;<br />};
~MyObject()
<br />#include &quot;main.moc&amp;quot;  
{}
<br />int main(int argc, char** argv)<br />{<br /> QApplication app(argc, argv);<br /> QDeclarativeView view;<br /> qmlRegisterType&amp;lt;MyObject&amp;gt;(&quot;QtQuick&amp;quot;, 1, 0, &quot;MyObject&amp;quot;);<br /> view.setSource(QUrl::fromLocalFile&amp;amp;#40;&quot;test.qml&amp;quot;&amp;#41;);<br /> view.show();<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br /></code>
QDeclarativeListProperty<MyObject> getInfo()
<br />Due to the way that QDeclarativeListProperty works it is necessary to keep the QList around while the property is valid which is why it is a member of the class here.
{
<br />The following QML file shows how the class above can be used and cleared in qml.
for (int i = 0; i < 10; +''i)
<br /><code><br />import QtQuick 1.0
{
<br />Rectangle {<br /> id: page<br /> width: 500; height: 200<br /> color: &quot;red&amp;quot;
list << new MyObject();
<br /> MyObject<br /> {<br /> id: myObject<br /> Component.onCompleted: {<br /> print(&quot;completed…&quot;'' myObject.getInfo);
}
return QDeclarativeListProperty<MyObject>(this, 0, &amp;MyObject::appendObject, 0, 0, &amp;MyObject::clearObject);
}
static void appendObject(QDeclarativeListProperty<MyObject> *l, MyObject *obj)
{
MyObject '''object = qobject_cast<MyObject'''>(l->object);
if (object)
object->list << obj;
}
static void clearObject(QDeclarativeListProperty<MyObject> *l)
{
MyObject '''object = qobject_cast<MyObject'''>(l->object);
if (object) {
foreach (MyObject '''o, object->list)
delete o;
object->list.clear();
}
}
QList<MyObject'''> list;
};  


for (var i=0; i&amp;lt;100; ++i) {<br /> myObject.getInfo = [];<br /> }<br /> }<br /> }<br />}<br /></code>
#include "main.moc"
 
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QDeclarativeView view;
qmlRegisterType<MyObject>("QtQuick", 1, 0, "MyObject");
view.setSource(QUrl::fromLocalFile("test.qml"));
view.show();
return app.exec();
}
</code>
 
Due to the way that QDeclarativeListProperty works it is necessary to keep the QList around while the property is valid which is why it is a member of the class here.
 
The following QML file shows how the class above can be used and cleared in qml.
 
<code>
import QtQuick 1.0
 
Rectangle {
id: page
width: 500; height: 200
color: "red"
 
MyObject
{
id: myObject
Component.onCompleted: {
print("completed…"'' myObject.getInfo);
 
for (var i=0; i<100; ++i) {
myObject.getInfo = [];
}
}
}
}
</code>


Note that in order to clear it, it is necessary to do:
Note that in order to clear it, it is necessary to do:
Line 40: Line 107:
as Javascript doesn't know when to clear it otherwise.
as Javascript doesn't know when to clear it otherwise.


The Qt documentation provides the following &quot;example&amp;quot;:http://doc.qt.nokia.com/latest/declarative-tutorials-extending-chapter5-listproperties.html that can be useful to have a look at as well.
The Qt documentation provides the following "example":http://doc.qt.nokia.com/latest/declarative-tutorials-extending-chapter5-listproperties.html that can be useful to have a look at as well.


== Dynamic alteration of lists ==
== Dynamic alteration of lists ==


Dynamic alteration of lists is not well supported right now, due to issues with bindings and lists. The current way to alter a list is to assign a new list in its place.
Dynamic alteration of lists is not well supported right now, due to issues with bindings and lists. The current way to alter a list is to assign a new list in its place.

Revision as of 09:07, 25 February 2015

[toc align_right="yes" depth="2"]

English Ελληνικά

How to expose lists to QML

Which class to use?

"QDeclarativeListProperty":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html allows you to expose list like properties to QML. When implementing the function pointers in this class, memory management will be taken care of for you and the bindings will work correctly as well. Using a standard "QList ":http://doc.qt.nokia.com/latest/qlist.html instead of QDeclarativeListProperty, will not take care of memory management and can cause your application to leak. In addition QList does not provide notification signals when children change. So when simply using a QList, the bindings won't work properly either. QDeclarativeListProperty is hence the recommended class to use for lists in QML.

Which constructor to use?

QDeclarativeListProperty provides 2 constructors. The "first one":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty taking a QList is there for convenience and should only be used for prototyping since it does not clean up memory for you. It still connects up the bindings properly and is therefore recommended over using a simple QList.

The second "QDeclarativeListProperty constructor":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty-3 constructs a QDeclarativeListProperty from a set of operation functions. It works by passing functions to be called when appending, clearing, counting and getting the current position, but only the append function is necessary to implement. This is the constructor you should use in production code.

Example on how to use QDeclarativeListProperty

The following example shows how the "QDeclarativeListProperty::AppendFunction":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#AppendFunction-typedef and "QDeclarativeListProperty::ClearFunction ":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#ClearFunction-typedef can be implemented:

#include <QtGui>
#include <QtDeclarative>

class MyObject : public QObject
{
 Q_OBJECT
 Q_PROPERTY(QDeclarativeListProperty<MyObject> getInfo READ getInfo CONSTANT)
public:
 MyObject()
 {}

~MyObject()
 {}
 QDeclarativeListProperty<MyObject> getInfo()
 {
 for (int i = 0; i < 10; +''i)
 {
 list << new MyObject();
 }
 return QDeclarativeListProperty<MyObject>(this, 0, &amp;MyObject::appendObject, 0, 0, &amp;MyObject::clearObject);
 }
 static void appendObject(QDeclarativeListProperty<MyObject> *l, MyObject *obj)
 {
 MyObject '''object = qobject_cast<MyObject'''>(l->object);
 if (object)
 object->list << obj;
 }
 static void clearObject(QDeclarativeListProperty<MyObject> *l)
 {
 MyObject '''object = qobject_cast<MyObject'''>(l->object);
 if (object) {
 foreach (MyObject '''o, object->list)
 delete o;
 object->list.clear();
 }
 }
 QList<MyObject'''> list;
}; 

#include "main.moc" 

int main(int argc, char** argv)
{
 QApplication app(argc, argv);
 QDeclarativeView view;
 qmlRegisterType<MyObject>("QtQuick", 1, 0, "MyObject");
 view.setSource(QUrl::fromLocalFile("test.qml"));
 view.show();
 return app.exec();
}

Due to the way that QDeclarativeListProperty works it is necessary to keep the QList around while the property is valid which is why it is a member of the class here.

The following QML file shows how the class above can be used and cleared in qml.

import QtQuick 1.0 

Rectangle {
 id: page
 width: 500; height: 200
 color: "red" 

 MyObject
 {
 id: myObject
 Component.onCompleted: {
 print("completed…"'' myObject.getInfo);

for (var i=0; i<100; ++i) {
 myObject.getInfo = [];
 }
 }
 }
}

Note that in order to clear it, it is necessary to do:

myObject.getInfo = []

as Javascript doesn't know when to clear it otherwise.

The Qt documentation provides the following "example":http://doc.qt.nokia.com/latest/declarative-tutorials-extending-chapter5-listproperties.html that can be useful to have a look at as well.

Dynamic alteration of lists

Dynamic alteration of lists is not well supported right now, due to issues with bindings and lists. The current way to alter a list is to assign a new list in its place.