Как получить доступ к свойствам делегата в ListView, используя индекс

Я хочу получить доступ к свойствам делегата в 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

4 ответа

Решение

Прежде всего: если вы пытаетесь получить доступ к элементам списка за пределами вашего списка, это хороший индикатор того, что вам следует переосмыслить свой дизайн.

Теперь решение: у списка есть больше детей, чем только его элементов. Вы можете отфильтровать их, определив, например, свойство "тип строки свойства: "myType" ". Затем найдите элементы, перебрав их по дочерним элементам, и возьмите только те, у которых свойство type равно "myType". Это что-то вроде хака, но опять же, вы не должны делать это в первую очередь.

@Teimpz не очень хорошо объяснил это. Тем более, что существует множество примеров qt project и ubuntu touch qml и случаев использования, когда вы управляете динамически создаваемыми элементами списка с помощью javascript, и поэтому у них есть методы и свойства javascript

В QML понятие родителя больше, чем потомка, что часто встречается в html. В больших проектах это рекомендуется (как вы также можете видеть в примерах qt и в документах http://doc.qt.io/qt-5/qtqml-javascript-expressions.html) чтобы логика js была отделена от элементов qml, чтобы вы обращались к элементам извне и управляли ими, а не загрязняли ваши элементы qml с помощью логики js, но не для поиска дочерних элементов, а для демонстрации необходимых вам дочерних элементов.

В вашем случае вы должны просто использовать currentItemтак же, как вы используете currentIndex, так currentItem.count даст вам то, что вам нужно. И если вам не нужен текущий элемент вообще, вы можете получить доступ к элементам из модели напрямую:

modelData.get(currentIndex).count, или же listview.model.get(currentIndex).count

Что касается взлома, упомянутого @Teimpz, это тоже один плохой пример. Если у вас есть более сложные требования и вам нужны определенные элементы внутри делегата, у каждого делегата есть свойство ListView.isCurrentItem, которое вы можете прикрепить и проверить. Это будет означать, что вы можете добавить свойство var myTargetItem в listview и установить его из дочернего элемента в любой элемент, который вы хотите, если этот делегат является текущим http://doc.qt.io/qt-5/qml-qtquick-listview.html

Конечно, вы можете сделать это для любого типа события, возможно, activeFocus, чтобы вы могли ссылаться только на элемент activeFocused.

Это еще раз дает вам возможность выставлять только нужные элементы без какой-либо продвинутой логики или блокировки. Комбинируя это с сигналами, вы можете создавать очень сложные, но чистые интерфейсы, не просматривая дочерние элементы.

Так что, в конце концов, возможно, это будет не так приятно, но все же лучше, чем поиск элементов. property int currentItemCount: 0 на просмотр списка. В делегат (элемент Row) вы затем добавляете property bool isCurrentItem: ListView.isCurrentItemтак что вы получите onIsCurrentItemChanged сигнал внутри делегата, где вы можете сделать: onIsCurrentItemChanged: if(isCurrentItem) listview.currentItemCount = count так что у вас всегда есть текущий счетчик предметов

Простой способ - использоватьitemAtIndex()нравитьсяintemAt()вRepeater.

      myListView.itemAtIndex(currentIndex)).function_name()
Другие вопросы по тегам