Results 1 to 7 of 7

Thread: property binding in a repeater

  1. #1
    Join Date
    Jan 2012
    Location
    Dortmund, Germany
    Posts
    159
    Thanks
    69
    Thanked 10 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Windows Android

    Question property binding in a repeater

    Hi,
    I have an item with 12 text fields, laid out as a grid and produced with a repeater.
    Now I want to make bindings to one property each (line 29). How can I do that elegantly?

    I don't even know which words to use for a google search on this...
    I can imagine it might be possible with some kind of list in the property section?

    Here's a condensed code that should clarify what I mean:

    Qt Code:
    1. import QtQuick 2.2
    2. import QtQuick.Controls 1.1
    3.  
    4. Item {
    5.  
    6. id: personButtonBasis
    7.  
    8. property string data00Text: ""
    9. property string data01Text: ""
    10. property string data02Text: ""
    11. property string data03Text: ""
    12. property string data04Text: ""
    13. property string data05Text: ""
    14. property string data06Text: ""
    15. property string data07Text: ""
    16. property string data08Text: ""
    17. property string data09Text: ""
    18. property string data10Text: ""
    19. property string data11Text: ""
    20.  
    21.  
    22. Grid {
    23. id: dataTextGrid
    24. columns: 3
    25. Repeater {
    26. id: dataFieldRepeater
    27. model:12
    28. Text {
    29. text: ???????????
    30. }
    31. }
    32.  
    33. }
    To copy to clipboard, switch view to plain text mode 

    I tried in vain to "compose" the property name as in this (non-working) example (located starting from line 29):
    Qt Code:
    1. Binding {
    2. target: personButtonBasis;
    3. property: (index<10)? "data0%1Text".arg(index) : "data%1Text".arg(index)
    4. value: text
    5. }
    To copy to clipboard, switch view to plain text mode 
    It might well be a very stupid question, as I am still very new to the QML world.
    Last edited by sedi; 22nd March 2015 at 12:56.

  2. #2
    Join Date
    Oct 2014
    Posts
    104
    Thanks
    16
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: property binding in a repeater

    I think you need to implement it using ListModel

    Qt Code:
    1. Item {
    2. id: personButtonBasis
    3.  
    4. ListModel {
    5. id: buttonModel
    6. ListElement {
    7. text: "Button 1"
    8. }
    9. ListElement {
    10. text: "Button 2"
    11. }
    12. ListElement {
    13. text: "Button 3"
    14. }
    15. ListElement {
    16. text: "Button 4"
    17. }
    18. }
    19.  
    20.  
    21. Grid {
    22. id: dataTextGrid
    23. columns: 3
    24. Repeater {
    25. id: dataFieldRepeater
    26. model: buttonModel
    27. Text {
    28. text: model.text
    29. }
    30. }
    31. }
    32. }
    To copy to clipboard, switch view to plain text mode 

  3. The following user says thank you to joko for this useful post:

    sedi (23rd March 2015)

  4. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: property binding in a repeater

    What you would usually do in such a situation is to have a model instead of all these string properties.

    In the easiest case the model would just be a list of strings

    Qt Code:
    1. Item {
    2. property var texts: [ "a", "b", c" ]
    3.  
    4. Repeater {
    5. model: parent.texts
    6.  
    7. Text {
    8. text: modelData
    9. }
    10. }
    11. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  5. The following user says thank you to anda_skoa for this useful post:

    sedi (23rd March 2015)

  6. #4
    Join Date
    Jan 2012
    Location
    Dortmund, Germany
    Posts
    159
    Thanks
    69
    Thanked 10 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Windows Android

    Red face Re: property binding in a repeater [SOLVED]

    Thanks, anda_skoa!
    That's exactly what I did - and it works! I have a rather complex model with several lists in it and it was not easy to get it done, but here are a few details for others with the same problem. This is not a compileable example (too big), it may have been shortened too much and may contain simplification mistakes - but it might perhaps be able to shorten the solution finding process of others anyway.

    I need several buttons, each with several data fields on it. The latter are defined here:
    Qt Code:
    1. class DataFieldContent: public QObject
    2. {
    3. Q_OBJECT
    4. Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
    5. Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
    6. signals:
    7. void textChanged();
    8. void colorChanged();
    9. public:
    10. [...]
    11.  
    12. //getters
    13. QString text();
    14. QColor color();
    15.  
    16. //setters
    17. void setText(QString text);
    18. void setColor(QColor color);
    19. };
    To copy to clipboard, switch view to plain text mode 

    All my data fields are organized in a C++ class "Content":
    Qt Code:
    1. class Content: public QObject
    2. {
    3. Q_OBJECT
    4. Q_PROPERTY(QQmlListProperty<DataFieldContent>dataFieldContents READ dataFieldContents NOTIFY dataFieldContentsChanged)
    5.  
    6. signals:
    7. void dataFieldContentsChanged();
    8. public:
    9. [...]
    10. QQmlListProperty<DataFieldContent> dataFieldContents() { return
    11. QQmlListProperty<DataFieldContent> (this,
    12. 0,
    13. &appendDataFieldContent,
    14. &dataFieldContentsCount,
    15. &dataFieldContentAt,
    16. &dataFieldContentsClear);
    17. }
    18.  
    19. static void appendDataFieldContent(QQmlListProperty<DataFieldContent> *list, DataFieldContent *p);
    20. static int dataFieldContentsCount(QQmlListProperty<DataFieldContent> *list);
    21. static DataFieldContent* dataFieldContentAt(QQmlListProperty<DataFieldContent> *list, int i);
    22. static void dataFieldContentsClear(QQmlListProperty<DataFieldContent> *list);
    23.  
    24. protected:
    25. QList<DataFieldContent*>m_dataFieldContents;
    To copy to clipboard, switch view to plain text mode 

    As I need a bunch of those Buttons, there is also a GroupContent, basically a List of Contents (Note that QList does not derive from QObject, you can't "just use" it).

    Qt Code:
    1. class GroupContent: public QObject
    2. {
    3. Q_OBJECT
    4. Q_PROPERTY(QQmlListProperty<Content> contents READ contents NOTIFY contentsChanged)
    5.  
    6. signals:
    7. void contentsChanged();
    8. public slots:
    9. void contentsChangedSlot();
    10.  
    11. public:
    12. [...]
    13. QQmlListProperty <Content> contents();
    14.  
    15. static void appendContent(QQmlListProperty<Content> *list, Content *p);
    16. static int contentsCount(QQmlListProperty<Content>*list);
    17. static Content* contentAt(QQmlListProperty<Content> *list, int i);
    18. static void contentsClear(QQmlListProperty<Content> *list);
    19.  
    20. void addContent(Content* p) { m_Contents.append(p);}
    21.  
    22.  
    23. protected:
    24. QList<Content*> m_Contents;
    25. };
    To copy to clipboard, switch view to plain text mode 

    On the QML side we need a display: MyButton.qml:

    Qt Code:
    1. Item {
    2. id: ButtonBasis
    3. property var dataFields;
    4.  
    5. Grid {
    6. [...]
    7. Repeater {
    8. id: dataFieldRepeater
    9. model: ButtonBasis.dataFields
    10. Text {
    11. text: dataFieldRepeater.model[index].text
    12. color: dataFieldRepeater.model[index].color
    13. [...]
    14.  
    15. }
    16. }
    17. }
    18. }
    To copy to clipboard, switch view to plain text mode 

    And all that is linked together in main.qml:

    Qt Code:
    1. Repeater {
    2. id: contentRepeater
    3. model: groupContent.contents
    4. delegate: MyButton {
    5. dataFields: contentRepeater.model[index].dataFieldContents
    6. [...]
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    Don't forget to register your classes to QML (e.g. in main.cpp) by:

    Qt Code:
    1. qmlRegisterType<DataFieldContent>("de.yourdomain.whatsoever.whatsoever",2,0,"DataFieldContent");
    2. qmlRegisterType<Content>("de.yourdomain.whatsoever.whatsoever",2,0,"Content");
    3. qmlRegisterType<GroupContent>("de.yourdomain.whatsoever.whatsoever",2,0,"GroupContent");
    To copy to clipboard, switch view to plain text mode 

  7. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: property binding in a repeater [SOLVED]

    Inside a delegate you can always address the current data entry like this

    Qt Code:
    1. model.property
    To copy to clipboard, switch view to plain text mode 

    E.g. in your case
    Qt Code:
    1. text: model.text
    2. color: model.color
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  8. The following user says thank you to anda_skoa for this useful post:

    sedi (1st April 2015)

  9. #6
    Join Date
    Jan 2012
    Location
    Dortmund, Germany
    Posts
    159
    Thanks
    69
    Thanked 10 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Windows Android

    Default Re: property binding in a repeater [SOLVED]

    You are right, of course. Normally that should be the easier solution. I have, although, tried that in vain before - probably the problem was my use of nested delegates - so "model" had to be specifically addressed.

  10. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: property binding in a repeater [SOLVED]

    In such a case I would suggest keeping the data locally referencable instead

    Qt Code:
    1. delegate: Item {
    2. id: delegateRoot
    3. readonly property text: model.text
    4.  
    5. Text {
    6. text: delegateRoot.text // or here also: parent.text
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 
    That way you can potentially use the delegate in other views, referencing the model through a named view binds it to that specific view instance (can't even rename the view without breaking the delegate!)

    Cheers,
    _

  11. The following user says thank you to anda_skoa for this useful post:

    sedi (2nd April 2015)

Similar Threads

  1. repeater polish() loop on ios
    By joko in forum Qt Quick
    Replies: 8
    Last Post: 13th March 2015, 15:35
  2. Access parent property from repeater
    By c1223 in forum Qt Quick
    Replies: 3
    Last Post: 28th November 2014, 06:11
  3. Dynamic QML Property Binding
    By EMCEE in forum Qt Quick
    Replies: 1
    Last Post: 30th August 2012, 11:51
  4. QML Property Binding update does not propagate
    By bluestreak in forum Qt Quick
    Replies: 0
    Last Post: 21st August 2012, 19:24
  5. Replies: 0
    Last Post: 17th October 2011, 13:07

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.