Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Dynamic delegate in Repeater



  • Hello,

    I want use Repeater with dynamic delegates.

    For example, I have this model :

     ListModel {
            id: listModelLabel
            ListElement {lib: "SITE"; type: "TEXT"}
            ListElement {lib: "REP"; type: "TEXT"}
            ListElement {lib: "FAB"; type: "AREA"}
    }
    

    and this components :

    Component {
        id: text
        Label { ... }
    }
    
    Component {
        id: area
        TextArea { ... }
    }
    

    In my Repeater, if the current item has the property type = TEXT, so the delegate will be text. But if type = AREA, the delegate will be area

    But, this doesn't work.

    Here, the code of my repeater :

    Repeater {
                id: repeater
                model: listModelLabel
                delegate: {
                    if (listModelLabel[index].type === "TEXT"){
                        text
                    }
                    if (listModelLabel[index].type === "AREA"){
                        area
                    }
                }
            }
    

    Do you know, if this is possible ?

    Thank you for your help.

    Bye.

    Charlie


  • Qt Champions 2018

    You should use a Loader for that :

    Repeater {
        id: repeater
        model: listModelLabel
        Loader {
            sourceComponent: {
                if (listModelLabel[index].type === "TEXT") 
                    return text;
                if (listModelLabel[index].type === "AREA")
                    return area;
            }
        }
    }
    

    You could also use source instead of sourceComponent if you'd like to define your different delegates in their own file.



  • Completing the previous answer:

    • listModelLabel[index].type is not correct; use type instead, because it is automatically referring to the current element loaded from your List Model
    • I would suggest to use a Positioner (Row, Column, Grid, ...) for the repeater, otherwise everything will be overlapped. Add some spacing if needed.
    • Given the fact that both your components have a property called "text", you may change it according to the "lib" string in your model, for example. This is possible using "onLoaded" property of the Loader component.

    This is the code I used:

        ListModel {
           id: listModelLabel
           ListElement {lib: "SITE"; type: "TEXT"}
           ListElement {lib: "REP"; type: "TEXT"}
           ListElement {lib: "FAB"; type: "AREA"}
        }
    
        Component {
            id: text
            Label {
            }
        }
    
        Component {
            id: area
            TextArea {
            }
        }
    
        Column {
            Repeater {
                id: repeater
                model: listModelLabel
                delegate: Loader {
                    sourceComponent: {
                        if (type === "TEXT")
                            text;
                        if (type === "AREA")
                            area;
                    }
                    onLoaded: {
                        item.text = lib;
                    }
                }
            }
        }
    


  • Thank you. It works.



  • How to append multiple qml's in my ListView??
    Please help..



  • @Surajkumar-Tanurkar would you mind creating a new post for your question?

    You're using a topic already marked as solved, and with no activity since 3 years ago, come on...


Log in to reply