1
votes

How can I assign different models to a ListView, which is inside a Repeater? I did a sketch (my actual project is much larger):

Column {
    Repeater {
        model: ["Line1","Line2","Line3","Line4"]
        Rectangle {
            ListView {
                model: ???
                delegate: Rectangle {
                    Text {
                        text: somemodelproperty
                    }                
                }
            }
        }
    }
}

Currently, I am solving the idea by copy-pasting 10 Rectangles, each containing a ListView. In C++, I have implemented 10 QList<QObject*>, and each list is "bounded" to a ListView by doing

QQmlContext * example = engine.rootContext();
example->setContextProperty(modelname,QVariant::fromValue(listobject));

I am pretty sure there is a more intelligent way to do this, but I have just started working with QML a few days ago, and can't figure out a solution.

2

2 Answers

2
votes

There is the catch, you can't use an id as a value for a list element, nor can you nest a list model inside a list element, at least not directly.

You can however populate it like this:

Item {
    id: models
    ListModel {/*...*/}
    ListModel {/*...*/}
    //...
}

ListModel {
    id: outerModel
}

function set() {
    for (var i = 0; i < models.data.length; ++i) {
        outerModel.append({"model": models.data[i] /* and other stuff */})
    }
}

Or if you prefer using your C++ data, you can add a QObject* "model" property to each of the elements in the list and set it with a function, either as in the example above or with the ids for the inner models you specify.

On a second thought, you might want to use another name instead of "model" because I can't imagine QML will be happy about something like model: model

Update: You could try doing something like this (assuming your 10 models are exposed as m1 - m10 in QML)

property var subModels: [m1, m2, ... m10]

Then for the ListView inside the repeater delegate you can:

ListView {
    model: subModels[index]
    // ...
}

Then assuming you have 10 elements in the repeater, the model for each list view will be selected from the array with the appropriate element index.

1
votes

Declare model for repeater instead of using array of strings. You can use ListModel for that purposes. You can also add to ListModels element, ListElement, any properties you want. Declare something like following:

ListModel { 
   id: repeaterModel
   ListElement { title: "Line1"; model: modelForFirstElement; }
   ListElement { title: "Line2"; model: modelForSecondElement; }
   // ...
}

Then assign it to your Repeater's model property

Repeater {
   id: repeater
   model: repeaterModel
// ...

Then you will be able to access to model for your ListView by just calling model's model property, like this (assuming that you have assigned id "repeater" for your Repeater element):

ListView {
   model: repeater.model.model
// ...