【问题标题】:QML ListView inside Repeater中继器内的 QML ListView
【发布时间】:2015-04-01 07:52:57
【问题描述】:

如何将不同的模型分配给ListView,它位于Repeater 中? 我做了一个草图(我的实际项目要大得多):

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

目前,我正在通过复制粘贴 10 个矩形来解决这个问题,每个矩形都包含一个 ListView。在 C++ 中,我已经实现了 10 个QList<QObject*>,并且每个列表都“绑定”到一个ListView

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

我很确定有一种更智能的方法可以做到这一点,但我几天前才开始使用 QML,还没有找到解决方案。

【问题讨论】:

    标签: c++ qt listview qml repeater


    【解决方案1】:

    有一个问题,你不能将id 用作列表元素的值,也不能将列表模型嵌套在列表元素中,至少不能直接嵌套。

    但是,您可以像这样填充它:

    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 */})
        }
    }
    

    或者,如果您更喜欢使用 C++ 数据,您可以将 QObject* "model" 属性添加到列表中的每个元素并使用函数设置它,如上例所示或使用 id s 代表您指定的内部模型。

    再想一想,您可能想要使用另一个名称而不是“模型”,因为我无法想象 QML 会为 model: model 之类的东西感到高兴

    更新:您可以尝试这样做(假设您的 10 个模型在 QML 中公开为 m1 - m10

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

    那么对于转发器委托中的ListView,您可以:

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

    然后假设转发器中有 10 个元素,每个列表视图的模型将从具有适当元素索引的数组中选择。

    【讨论】:

    • 您能否详细说明您的答案?我想使用我的 C++ 数据,它们是 QObject*s 的列表。我应该在 Item 中的 ListModels 中添加什么? repeater 中的所有内容在哪里?谢谢。
    • +1,只是别名 model 具有另一个名称的属性,并绑定到该属性(即在您无法重命名的情况下)
    【解决方案2】:

    声明转发器的模型而不是使用字符串数组。您可以为此目的使用 ListModel。您还可以向 ListModels 元素、ListElement 添加所需的任何属性。声明如下:

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

    然后将其分配给中继器的模型属性

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

    然后你就可以通过调用模型的模型属性来访问你的 ListView 的模型,就像这样(假设你已经为你的 Repeater 元素分配了 id “repeater”):

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

    【讨论】:

    • 感谢您的回答。但是,我遇到了一个问题:使用建议的 ListModel 时,我得到"ListElement: cannot use script for property value" 显然是因为 ListElement 中的模型。
    • 好吧,ListElement 似乎只能处理简单的值,比如字符串或整数值。因此,不要在其中分配/声明指向模型或模型本身的指针。相反,分配字符串值,如model: "modelForFirstElement" 等。然后,在repeaterModel 中声明属性,如:property var subModels: { "modelForFirstElement": modelForFirstElement, "modelForSecondElement": modelForSecondElement } 等。然后将model: repeater.model.model 更改为repeater.model.subModels[ repeater.model.model ]。如果可行,请发表评论 - 我将编辑我的答案。
    • 我已经尝试了你的建议,我在repeater.model.subModels[ repeater.model.model ] 收到了TypeError: Cannot read property 'undefined' of undefined。我已经仔细检查了代码以确保 ids 都正确写入。不幸的是,Qt 不支持在 ListElements 中包含模型,因为这将是解决这个问题的最合乎逻辑的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-05-22
    • 2019-07-15
    • 2019-08-13
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多