中继器内的 QML ListView

Posted

技术标签:

【中文标题】中继器内的 QML ListView【英文标题】:QML ListView inside Repeater 【发布时间】: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,还没有找到解决方案。

【问题讨论】:

【参考方案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 中包含模型,因为这将是解决这个问题的最合乎逻辑的解决方案。

以上是关于中继器内的 QML ListView的主要内容,如果未能解决你的问题,请参考以下文章

QML ListElement 传递字符串列表

列数可变的 QML 中继器和 QML 网格布局

QML:在中继器上调用 itemAt 返回 null

qml 使用中继器从 Qlist 绘制折线图

QML 使用中继器和委托,显示旧列表

更改模型后未正确绘制 QML 中继器