How to expose lists to QML/el: 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]]<br />[[Category:Developing_with_Qt::General]]<br />[[Category:Tutorial]]<br />[toc align_right="yes" depth="2"]


'''Ελληνικά''' [[How_to_expose_lists_to_QML|English]]
'''Ελληνικά''' [[How_to_expose_lists_to_QML|English]]
Line 7: Line 7:
== Ποιες κλάσεις να χρησιμοποιήσετε; ==
== Ποιες κλάσεις να χρησιμοποιήσετε; ==


Η &quot;QDeclarativeListProperty&amp;quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html σας επιτρέπει να χρησιμοποιήσετε (κάνει expose) τις λίστες ως ιδιότητες στην QML. Όταν υλοποιείτε τους function pointers σε αυτή την κλάση, η διαχείριση μνήμης θα γίνει αυτόματα και τα bindings θα δουλεύουν σωστά. Χρησιμοποιώντας μία στάνταρ &quot;QList &quot;:http://doc.qt.nokia.com/latest/qlist.html αντί για μια QDeclarativeListProperty, δεν θα λάβει χώρα η αυτόματη διαχείριση μνήμης με πιθανό κίνδυνο leak της εφαρμογής σας. Επιπρόσθετα, η QList δεν παρέχει σήματα ειδοποίησης (notification signals) όταν τα παιδιά της (children) τροποποιούνται. Έτσι, όταν χρησιμοποιείτε μια QList, τα bindings δεν θα λειτουργούν σωστά. Συνεπώς, η QDeclarativeListProperty είναι η ενδεδειγμένη κλάση για χρήση λιστών στην QML.
Η "QDeclarativeListProperty":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html σας επιτρέπει να χρησιμοποιήσετε (κάνει expose) τις λίστες ως ιδιότητες στην QML. Όταν υλοποιείτε τους function pointers σε αυτή την κλάση, η διαχείριση μνήμης θα γίνει αυτόματα και τα bindings θα δουλεύουν σωστά. Χρησιμοποιώντας μία στάνταρ "QList ":http://doc.qt.nokia.com/latest/qlist.html αντί για μια QDeclarativeListProperty, δεν θα λάβει χώρα η αυτόματη διαχείριση μνήμης με πιθανό κίνδυνο leak της εφαρμογής σας. Επιπρόσθετα, η QList δεν παρέχει σήματα ειδοποίησης (notification signals) όταν τα παιδιά της (children) τροποποιούνται. Έτσι, όταν χρησιμοποιείτε μια QList, τα bindings δεν θα λειτουργούν σωστά. Συνεπώς, η QDeclarativeListProperty είναι η ενδεδειγμένη κλάση για χρήση λιστών στην QML.


== Ποιον constructor να χρησιμοποιήσω? ==
== Ποιον constructor να χρησιμοποιήσω? ==


Η QDeclarativeListProperty παρέχει 2 constructors. Ο &quot;πρώτος&amp;quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty με όρισμα μία QList παρέχεται για διευκόλυνση και πρέπει να χρησιμοποιείται μόνο για prototyping καθώς δεν κάνει αυτόματη διαχείριση μνήμης. Σε κάθε περίπτωση, ενώνει τα bindings κατάλληλα και για το λόγο αυτό προτείνεται σε σχέση με την απλή χρήση μιας QList.
Η QDeclarativeListProperty παρέχει 2 constructors. Ο "πρώτος":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty με όρισμα μία QList παρέχεται για διευκόλυνση και πρέπει να χρησιμοποιείται μόνο για prototyping καθώς δεν κάνει αυτόματη διαχείριση μνήμης. Σε κάθε περίπτωση, ενώνει τα bindings κατάλληλα και για το λόγο αυτό προτείνεται σε σχέση με την απλή χρήση μιας QList.


Ο δεύτερος &quot;QDeclarativeListProperty constructor&amp;quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty-3 κατασκευάζει μια QDeclarativeListProperty από ένα σύνολο από operation functions. Λειτουργεί με το πέρασμα συναρτήσεων που καλούνται κατά την επέκταση, τον καθαρισμό, το μέτρημα και τη λήψη της τρέχουσας θέσης, αλλά απαιτείται να υλοποιήσετε μόνο την συνάρτηση επέκτασης. Αυτός είναι ο constructor που πρέπει να χρησιμοποιήσετε σε κώδικα παραγωγής (production code).
Ο δεύτερος "QDeclarativeListProperty constructor":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty-3 κατασκευάζει μια QDeclarativeListProperty από ένα σύνολο από operation functions. Λειτουργεί με το πέρασμα συναρτήσεων που καλούνται κατά την επέκταση, τον καθαρισμό, το μέτρημα και τη λήψη της τρέχουσας θέσης, αλλά απαιτείται να υλοποιήσετε μόνο την συνάρτηση επέκτασης. Αυτός είναι ο constructor που πρέπει να χρησιμοποιήσετε σε κώδικα παραγωγής (production code).


== Παράδειγμα για τη χρήση της QDeclarativeListProperty ==
== Παράδειγμα για τη χρήση της QDeclarativeListProperty ==


Το παρακάτω παράδειγμα δείχνει το πώς η &quot;QDeclarativeListProperty::AppendFunction&amp;quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#AppendFunction-typedef και η &quot;QDeclarativeListProperty::ClearFunction &quot;:http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#ClearFunction-typedef μπορούν να υλοποιηθούν:
Το παρακάτω παράδειγμα δείχνει το πώς η "QDeclarativeListProperty::AppendFunction":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#AppendFunction-typedef και η "QDeclarativeListProperty::ClearFunction ":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#ClearFunction-typedef μπορούν να υλοποιηθούν:


<code><br />#include &lt;QtGui&amp;gt;<br />#include &lt;QtDeclarative&amp;gt;
<code><br />#include <QtGui><br />#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<br />{<br /> Q_OBJECT<br /> Q_PROPERTY(QDeclarativeListProperty<MyObject> getInfo READ getInfo CONSTANT)<br />public:<br /> MyObject()<br /> {}


~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 /> {}<br /> QDeclarativeListProperty<MyObject> getInfo()<br /> {<br /> for (int i = 0; i < 10; +''i)<br /> {<br /> list << new MyObject();<br /> }<br /> return QDeclarativeListProperty<MyObject>(this, 0, &amp;MyObject::appendObject, 0, 0, &amp;MyObject::clearObject);<br /> }<br /> static void appendObject(QDeclarativeListProperty<MyObject> *l, MyObject *obj)<br /> {<br /> MyObject '''object = qobject_cast<MyObject'''>(l->object);<br /> if (object)<br /> object->list << obj;<br /> }<br /> static void clearObject(QDeclarativeListProperty<MyObject> *l)<br /> {<br /> MyObject '''object = qobject_cast<MyObject'''>(l->object);<br /> if (object) {<br /> foreach (MyObject '''o, object->list)<br /> delete o;<br /> object->list.clear();<br /> }<br /> }<br /> QList<MyObject'''> list;<br />};  
<br />#include &quot;main.moc&amp;quot;
<br />#include "main.moc"
<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>
<br />int main(int argc, char** argv)<br />{<br /> QApplication app(argc, argv);<br /> QDeclarativeView view;<br /> qmlRegisterType<MyObject>("QtQuick", 1, 0, "MyObject");<br /> view.setSource(QUrl::fromLocalFile("test.qml"));<br /> view.show();<br /> return app.exec();<br />}<br /></code>
<br />Λόγω του τρόπου που η QDeclarativeListProperty λειτουργεί είναι απαραίτητο να κρατάτε διαθέσιμη την QList όσο η ιδιότητα είναι έγκυρη και αυτός είναι ο λόγος για τον οποίο είναι μέλος της κλάσης εδώ.  
<br />Λόγω του τρόπου που η QDeclarativeListProperty λειτουργεί είναι απαραίτητο να κρατάτε διαθέσιμη την QList όσο η ιδιότητα είναι έγκυρη και αυτός είναι ο λόγος για τον οποίο είναι μέλος της κλάσης εδώ.  
<br />Το ακόλουθο αρχείο QML δείχνει το πώς η παραπάνω κλάση μπορεί να χρησιμοποιηθεί και να καθαριστεί στην qml.
<br />Το ακόλουθο αρχείο QML δείχνει το πώς η παραπάνω κλάση μπορεί να χρησιμοποιηθεί και να καθαριστεί στην qml.
<br /><code><br />import QtQuick 1.0  
<br /><code><br />import QtQuick 1.0  
<br />Rectangle {<br /> id: page<br /> width: 500; height: 200<br /> color: &quot;red&amp;quot;
<br />Rectangle {<br /> id: page<br /> width: 500; height: 200<br /> color: "red"
<br /> MyObject<br /> {<br /> id: myObject<br /> Component.onCompleted: {<br /> print(&quot;completed…&quot;'' myObject.getInfo);
<br /> MyObject<br /> {<br /> id: myObject<br /> Component.onCompleted: {<br /> print("completed…"'' myObject.getInfo);


for (var i=0; i&amp;lt;100; ++i) {<br /> myObject.getInfo = [];<br /> }<br /> }<br /> }<br />}<br /></code>
for (var i=0; i<100; ++i) {<br /> myObject.getInfo = [];<br /> }<br /> }<br /> }<br />}<br /></code>


Σημειώστε ότι για τον καθαρισμό είναι απαραίτητο να κάνετε το εξής:
Σημειώστε ότι για τον καθαρισμό είναι απαραίτητο να κάνετε το εξής:
Line 40: Line 40:
καθώς η Javascript δεν θα ξέρει αλλιώς πότε να κάνει τον καθαρισμό.
καθώς η Javascript δεν θα ξέρει αλλιώς πότε να κάνει τον καθαρισμό.


Η τεκμηρίωση του Qt παρέχει το ακόλουθο &quot;παράδειγμα&amp;quot;:http://doc.qt.nokia.com/latest/declarative-tutorials-extending-chapter5-listproperties.html το οποίο μπορεί να σας φανεί χρήσιμο να του ρίξετε μια ματιά.
Η τεκμηρίωση του Qt παρέχει το ακόλουθο "παράδειγμα":http://doc.qt.nokia.com/latest/declarative-tutorials-extending-chapter5-listproperties.html το οποίο μπορεί να σας φανεί χρήσιμο να του ρίξετε μια ματιά.


== Δυναμική τροποποίηση των λιστών ==
== Δυναμική τροποποίηση των λιστών ==


Η δυναμική τροποποίηση των λιστών δεν υποστηρίζεται σωστά ακόμη, λόγω ζητημάτων με τα bindings και τις λίστες. Ο τρέχων τρόπος τροποποίησης μιας λίστας είναι η ανάθεση μιας νέας λίστας στη θέση της.
Η δυναμική τροποποίηση των λιστών δεν υποστηρίζεται σωστά ακόμη, λόγω ζητημάτων με τα bindings και τις λίστες. Ο τρέχων τρόπος τροποποίησης μιας λίστας είναι η ανάθεση μιας νέας λίστας στη θέση της.

Revision as of 06:44, 25 February 2015




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

Ελληνικά English

Πώς να χρησιμοποιήσετε λίστες στην QML

Ποιες κλάσεις να χρησιμοποιήσετε;

Η "QDeclarativeListProperty":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html σας επιτρέπει να χρησιμοποιήσετε (κάνει expose) τις λίστες ως ιδιότητες στην QML. Όταν υλοποιείτε τους function pointers σε αυτή την κλάση, η διαχείριση μνήμης θα γίνει αυτόματα και τα bindings θα δουλεύουν σωστά. Χρησιμοποιώντας μία στάνταρ "QList ":http://doc.qt.nokia.com/latest/qlist.html αντί για μια QDeclarativeListProperty, δεν θα λάβει χώρα η αυτόματη διαχείριση μνήμης με πιθανό κίνδυνο leak της εφαρμογής σας. Επιπρόσθετα, η QList δεν παρέχει σήματα ειδοποίησης (notification signals) όταν τα παιδιά της (children) τροποποιούνται. Έτσι, όταν χρησιμοποιείτε μια QList, τα bindings δεν θα λειτουργούν σωστά. Συνεπώς, η QDeclarativeListProperty είναι η ενδεδειγμένη κλάση για χρήση λιστών στην QML.

Ποιον constructor να χρησιμοποιήσω?

Η QDeclarativeListProperty παρέχει 2 constructors. Ο "πρώτος":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty με όρισμα μία QList παρέχεται για διευκόλυνση και πρέπει να χρησιμοποιείται μόνο για prototyping καθώς δεν κάνει αυτόματη διαχείριση μνήμης. Σε κάθε περίπτωση, ενώνει τα bindings κατάλληλα και για το λόγο αυτό προτείνεται σε σχέση με την απλή χρήση μιας QList.

Ο δεύτερος "QDeclarativeListProperty constructor":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#QDeclarativeListProperty-3 κατασκευάζει μια QDeclarativeListProperty από ένα σύνολο από operation functions. Λειτουργεί με το πέρασμα συναρτήσεων που καλούνται κατά την επέκταση, τον καθαρισμό, το μέτρημα και τη λήψη της τρέχουσας θέσης, αλλά απαιτείται να υλοποιήσετε μόνο την συνάρτηση επέκτασης. Αυτός είναι ο constructor που πρέπει να χρησιμοποιήσετε σε κώδικα παραγωγής (production code).

Παράδειγμα για τη χρήση της QDeclarativeListProperty

Το παρακάτω παράδειγμα δείχνει το πώς η "QDeclarativeListProperty::AppendFunction":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#AppendFunction-typedef και η "QDeclarativeListProperty::ClearFunction ":http://doc.qt.nokia.com/latest/qdeclarativelistproperty.html#ClearFunction-typedef μπορούν να υλοποιηθούν:

<br />#include <QtGui><br />#include <QtDeclarative>

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

~MyObject()<br /> {}<br /> QDeclarativeListProperty<MyObject> getInfo()<br /> {<br /> for (int i = 0; i < 10; +''i)<br /> {<br /> list << new MyObject();<br /> }<br /> return QDeclarativeListProperty<MyObject>(this, 0, &amp;MyObject::appendObject, 0, 0, &amp;MyObject::clearObject);<br /> }<br /> static void appendObject(QDeclarativeListProperty<MyObject> *l, MyObject *obj)<br /> {<br /> MyObject '''object = qobject_cast<MyObject'''>(l->object);<br /> if (object)<br /> object->list << obj;<br /> }<br /> static void clearObject(QDeclarativeListProperty<MyObject> *l)<br /> {<br /> MyObject '''object = qobject_cast<MyObject'''>(l->object);<br /> if (object) {<br /> foreach (MyObject '''o, object->list)<br /> delete o;<br /> object->list.clear();<br /> }<br /> }<br /> QList<MyObject'''> list;<br />}; 
<br />#include "main.moc" 
<br />int main(int argc, char** argv)<br />{<br /> QApplication app(argc, argv);<br /> QDeclarativeView view;<br /> qmlRegisterType<MyObject>("QtQuick", 1, 0, "MyObject");<br /> view.setSource(QUrl::fromLocalFile("test.qml"));<br /> view.show();<br /> return app.exec();<br />}<br />


Λόγω του τρόπου που η QDeclarativeListProperty λειτουργεί είναι απαραίτητο να κρατάτε διαθέσιμη την QList όσο η ιδιότητα είναι έγκυρη και αυτός είναι ο λόγος για τον οποίο είναι μέλος της κλάσης εδώ.
Το ακόλουθο αρχείο QML δείχνει το πώς η παραπάνω κλάση μπορεί να χρησιμοποιηθεί και να καθαριστεί στην qml.


<br />import QtQuick 1.0 
<br />Rectangle {<br /> id: page<br /> width: 500; height: 200<br /> color: "red" 
<br /> MyObject<br /> {<br /> id: myObject<br /> Component.onCompleted: {<br /> print("completed…"'' myObject.getInfo);

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

Σημειώστε ότι για τον καθαρισμό είναι απαραίτητο να κάνετε το εξής:

myObject.getInfo = []

καθώς η Javascript δεν θα ξέρει αλλιώς πότε να κάνει τον καθαρισμό.

Η τεκμηρίωση του Qt παρέχει το ακόλουθο "παράδειγμα":http://doc.qt.nokia.com/latest/declarative-tutorials-extending-chapter5-listproperties.html το οποίο μπορεί να σας φανεί χρήσιμο να του ρίξετε μια ματιά.

Δυναμική τροποποίηση των λιστών

Η δυναμική τροποποίηση των λιστών δεν υποστηρίζεται σωστά ακόμη, λόγω ζητημάτων με τα bindings και τις λίστες. Ο τρέχων τρόπος τροποποίησης μιας λίστας είναι η ανάθεση μιας νέας λίστας στη θέση της.