【问题标题】:How to access delegate properties in ListView using index如何使用索引访问 ListView 中的委托属性
【发布时间】:2015-11-19 17:17:22
【问题描述】:

我想访问ListView 中的委托属性。我试过contentItem,但有时是undefined

这是我的代码:

ListModel{
            id: modeldata
            ListElement{
                name:"don"
                rank:1
            }
            ListElement{
                name:"shan"
                rank:2
            }
            ListElement{
                name:"james"
                rank:3
            }
            ListElement{
                name:"jeggu"
                rank:4
            }
        }
        Component{
            id: delegateitem
            Row {
                property int count: rank
                Rectangle{
                    width: 100
                    height: 50
                    Text{
                        anchors.centerIn: parent
                        text: name
                    }
                }
            }
        }
        ListView{
            id: listview
            focus: true
            anchors.fill: parent
            model: modeldata
            delegate: delegateitem
            onCurrentIndexChanged: {
        console.log("position",currentIndex)
        console.log("property",contentItem.children[currentIndex].count);
            }
        }

位置 1 的问题输出无效

qml: position 0
qml: property 1
qml: position 1
qml: property undefined
qml: position 2
qml: property 2
qml: position 3
qml: property 3

【问题讨论】:

    标签: qml qt5 qtquick2


    【解决方案1】:

    @Teimpz 并没有很好地解释它。特别是因为有一堆 qt 项目和 ubuntu touch qml 示例和用例,您可以使用 javascript 管理动态创建的列表元素,这就是它们具有 javascript 方法和属性的原因

    在 QML 中,父母的概念多于孩子的概念,这在 html 中很常见。在更大的项目中,建议(正如您在 qt 示例和文档http://doc.qt.io/qt-5/qtqml-javascript-expressions.html#functions-in-imported-javascript-files 中看到的那样)将 js 逻辑与 qml 元素分开,这样您就可以从外部访问和管理元素,而不是用 js 逻辑污染您的 qml 元素,但是不是以查找子元素的方式,而是公开您需要的子元素。

    在你的情况下,你应该只使用currentItem,就像你使用currentIndex一样,所以currentItem.count会给你你需要的东西。 如果您根本不需要当前项目,您可以直接从模型中访问元素:

    modelData.get(currentIndex).count,或listview.model.get(currentIndex).count

    @Teimpz 提到的 hack 也是一个不好的例子。当您有更复杂的要求并希望在委托中包含特定元素时,每个委托都有 ListView.isCurrentItem 属性,您可以附加和检查该属性。这意味着您可以将属性 var myTargetItem 添加到 listview,如果该委托是当前的http://doc.qt.io/qt-5/qml-qtquick-listview.html#isCurrentItem-attached-prop

    您当然可以对任何类型的事件执行此操作,也许是 activeFocus,因此您只能引用 activeFocused 项目。

    这再次使您能够仅公开想要的元素,而无需任何高级逻辑或裁剪。将其与信号相结合,您可以创建非常复杂但干净的界面,而无需搜索子项。

    所以最后可能不太好但仍然比搜索元素更好的是添加property int currentItemCount: 0 到列表视图。然后在委托(行元素)中添加property bool isCurrentItem: ListView.isCurrentItem 所以你会在委托中得到onIsCurrentItemChanged 信号,你可以在其中执行以下操作: onIsCurrentItemChanged: if(isCurrentItem) listview.currentItemCount = count 所以你总是设置你当前的项目计数

    【讨论】:

    • 感谢您提供有关将 js 逻辑与 qml 分离的有用说明。
    【解决方案2】:

    首先:如果您尝试从列表之外访问列表元素,这是一个很好的指标,您应该重新考虑您的设计。

    现在的解决方案是:列表视图的子视图不仅仅是其项目。例如,您可以通过定义属性“属性字符串类型:“myType””来过滤掉它们。然后通过遍历子项来查找项目,并且只获取那些类型属性等于“myType”的项目。 它有点像黑客,但你真的不应该一开始就这样做。

    【讨论】:

    • 这将是笨拙的编码和运行缓慢。如果我错了,也许提供一个代码示例来演示
    • 我很想知道它是什么,虽然我知道我应该去源头。
    猜你喜欢
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多