简体   繁体   English

QML ListView 访问委托的一个项目

[英]QML ListView Acess To an Item of the delegate

this is my code:这是我的代码:

main.qml主要.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我的复选框.qml

CheckBox {
    id : chk
    width: 25
    height: 25
}

i wanna check on of the Checkbox with the Button OnClicked ( for example when i click, i Check the ItemAtIndex 2), to do this i need to access to the Object of my listview, there is a function available since QT 5.13 Item itemAtIndex(int index) but i'm using QT 5.12, is there another way to do it?我想用按钮 OnClicked 检查复选框(例如,当我单击时,我检查 ItemAtIndex 2),为此我需要访问我的列表视图的 Object,自 QT 5.13 ItemAtIndex( int index) 但我使用的是 QT 5.12,还有其他方法吗? Thanks for your help谢谢你的帮助

Trying to manually modify an item in a ListView is actually the wrong approach.尝试手动修改ListView中的项目实际上是错误的方法。 If you have 1000 items in your list, ListView is smart enough to not create 1000 delegate items.如果您的列表中有 1000 个项目, ListView足够聪明,不会创建 1000 个委托项目。 Instead, it creates only as many as it needs for the visible region of the list and reuses them with different model data as you scroll up and down.相反,它只创建列表可见区域所需的数量,并在您上下滚动时将它们与不同的 model 数据一起使用。 So because of that, if you try to access the item at index 987 for instance, that item might not even exist.因此,例如,如果您尝试访问索引 987 处的项目,则该项目甚至可能不存在。

The better way to do handle this is to include the checked state in your model, and update that model when you want the item to change.处理此问题的更好方法是将选中的 state 包含在您的 model 中,并在您希望更改项目时更新该 model。

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
            }
        }
    }
}

One way to achieve is creating a list of items.实现的一种方法是创建项目列表。 Add item to list onCompleted and remove onDestruction .将项目添加到列表onCompleted并删除onDestruction Or use onAdd and onRemove in ListView .或者在ListView中使用onAddonRemove Following code worked for me in 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;
            }
        }
    }
}

Update: Removing item by splice(index, 1) might disorder indexes of other items.更新:通过splice(index, 1)删除项目可能会打乱其他项目的索引。 So I think assigning undefined is a safer solution.所以我认为分配undefined是一个更安全的解决方案。

Note: Don't use this solution if you don't really have to get the item itself, otherwise checkout @JarMan's answer, using model is the right way to go.注意:如果您真的不需要自己获取物品,请不要使用此解决方案,否则请查看@JarMan 的回答,使用 model 是 go 的正确方法。

You can Use itemAtIndex() like intemAt() in Repeater .您可以像Repeater中的itemAtIndex() intemAt()

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

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