简体   繁体   English

QML Repeater 内的 ListView

[英]QML ListView inside Repeater

How can I assign different models to a ListView , which is inside a Repeater ?如何将不同的模型分配给Repeater内的ListView 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 .目前,我正在通过复制粘贴 10 个矩形来解决这个想法,每个矩形都包含一个ListView In C++, I have implemented 10 QList<QObject*> , and each list is "bounded" to a ListView by doing在 C++ 中,我实现了 10 个QList<QObject*> ,并且每个列表都“绑定”到一个ListView

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.我很确定有一种更智能的方法可以做到这一点,但我几天前才开始使用 QML,无法找到解决方案。

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. 有一个catch,你不能使用id作为list元素的值,也不能将列表模型嵌套在list元素中,至少不能直接嵌套。

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 id s for the inner models you specify. 或者,如果您更喜欢使用C ++数据,可以将QObject* “model”属性添加到列表中的每个元素,并使用函数进行设置,如上例所示,或者内部模型的id为指定。

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 再想一想,您可能想要使用另一个名称而不是“模型”,因为我无法想象QML会对model: model这样的东西感到高兴model: model

Update : You could try doing something like this (assuming your 10 models are exposed as m1 - m10 in QML) 更新 :您可以尝试这样做(假设您的10个模型在QML中公开为m1 - m10

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

Then for the ListView inside the repeater delegate you can: 然后对于转发器委托中的ListView ,您可以:

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. 然后假设转发器中有10个元素,将从具有相应元素索引的数组中选择每个列表视图的模型。

Declare model for repeater instead of using array of strings. 声明转发器的模型而不是使用字符串数组。 You can use ListModel for that purposes. 您可以将ListModel用于此目的。 You can also add to ListModels element, ListElement, any properties you want. 您还可以添加ListModels元素,ListElement,您想要的任何属性。 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的模型属性

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的模型,就像这样(假设你为Repeater元素分配了id“repeater”):

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

For the model, consider an array that has a sub-array nested within.对于 model,考虑一个嵌套有子数组的数组。 To differentiate since both the outer Repeater and the inner ListView have a different instance of modelData consider copying the outer modelData to a property named outerModelData .由于外部Repeater和内部ListView都具有不同的modelData实例,因此要进行区分,请考虑将外部modelData复制到名为outerModelData的属性。

In the following example, I refactor out Column - Repeater - ListView and replaced it with ListView - ListView .在下面的示例中,我重构了Column - Repeater - ListView并将其替换为ListView - ListView Both patterns achieve the same thing but the latter does it shorter.两种模式都实现了相同的目的,但后者做得更短。

import QtQuick
import QtQuick.Controls

Page {
    ListView {
        anchors.fill: parent
        model: [
            {la:"English",v:["one","two","three"]},
            {la:"Mandarin",v:["yi","er","san"]},
            {la:"French",v:["un","duex","trois"]},
            {la:"German",v:["eins","zwei","drei"]},
            {la:"Indonesian",v:["satu","dua","tiga"]},
        ]
        delegate: ListView {
            property var outerModelData: modelData
            width: 120
            height: childrenRect.height
            header: Text { text: outerModelData.la }
            model: outerModelData.v
            delegate: Frame {
                width: 100
                Text { text: modelData }                
            }
        }
    }
}

You can Try it Online!您可以在线试用!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM