QML ListView 访问委托的项目

Posted

技术标签:

【中文标题】QML ListView 访问委托的项目【英文标题】:QML ListView Acess To an Item of the delegate 【发布时间】:2021-01-28 21:10:00 【问题描述】:

这是我的代码:

main.qml

ApplicationWindow 
    visible: true
    width: 640
    height: 480
    title: qsTr("Scroll")

Button 
    id:btn
    x : 100
    y : 100
    text: "Click Her to check one of the checkbox! "

ScrollView 
    width: 40
    height: parent.height
    ListView 
        id : view
        width: parent.width
        leftMargin: 5
        model: 20
        delegate:
            MyCheckBox 
        
      
   

MyCheckBox.qml

CheckBox 
    id : chk
    width: 25
    height: 25

我想用 OnClicked 按钮检查复选框(例如,当我单击时,我检查 ItemAtIndex 2),为此我需要访问我的列表视图的对象,自 QT 5.13 起就有一个可用的功能项目 itemAtIndex(int index) 但我使用的是 QT 5.12,还有其他方法吗?感谢您的帮助

【问题讨论】:

【参考方案1】:

尝试手动修改ListView 中的项目实际上是错误的方法。如果您的列表中有 1000 个项目,ListView 足够聪明,不会创建 1000 个委托项目。相反,它只为列表的可见区域创建所需的数量,并在您上下滚动时将它们与不同的模型数据一起使用。因此,例如,如果您尝试访问索引 987 处的项目,则该项目甚至可能不存在。

处理此问题的更好方法是在模型中包含选中状态,并在您希望项目更改时更新该模型。

ApplicationWindow 
    visible: true
    width: 640
    height: 480
    title: qsTr("Scroll")

    ListModel 
        id: myModel
        ListElement 
            isChecked: false
        
        ListElement 
            isChecked: false
        
        ListElement 
            isChecked: false
        
        ListElement 
            isChecked: false
        
        ListElement 
            isChecked: false
        
    

    Button 
        id:btn
        x : 100
        y : 100
        text: "Click Her to check one of the checkbox! "

        // Check index 3
        onClicked: 
            myModel.set(3, "isChecked": true)
        
    

    ScrollView 
        width: 40
        height: parent.height
        ListView 
            id : view
            width: parent.width
            leftMargin: 5
            model: myModel
            delegate: MyCheckBox 
                checked: isChecked
            
        
    

【讨论】:

【参考方案2】:

实现的一种方法是创建项目列表。将项目添加到列表 onCompleted 并删除 onDestruction。或者在ListView 中使用onAddonRemove。 以下代码在online compiler 中为我工作:

import QtQuick 2.3
import QtQuick.Controls 2.12

ApplicationWindow 
    visible: true
    width: 640
    height: 480
    title: qsTr("Scroll")

    Button 
        property int checkBoxIndex: 5
        
        id:btn
        x : 100
        y : 100
        text: "Click Her to check one of the checkbox! "
        
        onClicked: 
            var item =  view.items[checkBoxIndex];
            
            if (item)
                item.toggle();
            else
                console.log("Item not found at index: " + checkBoxIndex);
        
    
    
    ScrollView 
        width: 40
        height: parent.height
        ListView 
            property var items: []
            
            id : view
            width: parent.width
            leftMargin: 5
            model: 20
            delegate: CheckBox 
                id : chk
                width: 25
                height: 25
                
                Component.onCompleted: view.items[index] = chk;
                Component.onDestruction: view.items[index] = undefined;
            
        
    

更新: 删除splice(index, 1) 的项目可能会导致其他项目的索引混乱。所以我认为分配undefined 是一个更安全的解决方案。

注意: 如果您真的不需要自己获取项目,请不要使用此解决方案,否则请查看@JarMan 的答案,使用模型是正确的方法。

【讨论】:

以上是关于QML ListView 访问委托的项目的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QML 中访问 ListView 的 ListModel 的 ListElement 的映射委托数据?

QML 阻止 ListView 委托一直更新

QML ListView隐藏的委托项

如何从QML中的GridView或ListView获取实例化的委托组件

QMLProfiler 中的 QML Listview 报告两次委托创建

获取当前显示的委托的索引 - QML ListView