Qml: Как установить свойство для всех элементов GridView - PullRequest
1 голос
/ 28 января 2020

Я пытаюсь внести изменения во все элементы GridView.
Я пытался перебрать либо модель, либо сетку, я смотрел похожие примеры в Интернете, но все, что я пробую, заканчивается Cannot read property 'buttonText' of undefined.

Мне кажется, что проблема в том, что переводчик не может понять, что элемент из сетки или модели является Button. Но я не знаю, как его разыграть.

Если я изменю журнал, чтобы отобразить только элемент, а не какое-либо свойство (см. Фрагмент кода), похоже, он знает, что это элемент ... см. мои эксперименты ниже.

Единственное, что я могу сделать, - это установить свойство (или вызвать сигнал, или функцию) из делегата. Но это влияет только на один элемент сетки, а не на все.

Как я могу установить свойство для каждого элемента сетки? В качестве альтернативы, как я могу отправить сигнал или вызвать функцию для каждого элемента?

Мои эксперименты находятся в function changeEverythingFunction()

файле: Button.qml

Item
{
    id: itemButton
    signal changeEverything

    property int buttonIndex
    property string buttonText

    ...
}

файл: Model.qml

Item
{
    id: modelItem

    ListModel
    {
        id: listModel
    }

    property int buttonCount: listModel.count

    function changeEverythingFunction()
    {
    //    for (var i = 0; i < buttonCount; i++)
    //        listModel.setProperty(i, buttonText, "abc")

        for(var childIndex in gridItems.contentItem.children) 
        {
            console.log(listModel.get(childIndex).buttonText)   // Cannot read property 'buttonText' of undefined
            console.log(gridItems.contentItem.children[childIndex].buttonText) // Cannot read property 'buttonText' of undefined
            console.log(gridItems.contentItem.children[childIndex]["buttonText"])   // undefined (I saw this in a SO example)

            var item = gridItems.contentItem.children[childIndex]
            console.log(item)   // qml: QQuickItem(0xe496370)
        }
    }

    MouseArea
    {
        ....
        Rectangle
        {
            ...

            GridView
            {
                id: gridItems

                anchors.fill: parent
                clip: true
                model: listModel

                delegate: Item
                {
                    id: buttonDelegate

                    Button
                    {
                        buttonIndex: gridId
                        buttonText: itemText

                        onChangeEverything:
                        {
                            changeEverythingFunction();
                        }
                    }
                }
            }
        }
    }
}

1 Ответ

1 голос
/ 28 января 2020

Ваш подход в обратном направлении: ваш подход заключается в том, чтобы получить элемент представления и изменить его, но подход, на который указывает Qt, состоит в том, что представление отражает информацию модели и изменяет ее при необходимости.

Ниже приведен простой пример, в котором каждый раз, когда вы нажимаете кнопку с текстом «измени меня», увеличивая отображаемое число, но если вы нажмете кнопку с текстом «изменить весь», она изменит все цифры. Как видно, все делается через модель, а не через представление, которое используется только для отображения информации или получения взаимодействия с пользователем.

import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14

Window {
    visible: true
    width: 640
    height: 480
    ListModel{
        id: listmodel
    }
    function changeAll(){
        for(var i=0; i< listmodel.count; ++i){
            listmodel.setProperty(i, "number", listmodel.get(i).number + 1)
        }
    }
    GridView{
        id: grid
        anchors.fill: parent
        clip: true
        model: listmodel
        cellHeight: 120
        cellWidth: 120
        delegate: Item {
            width: grid.cellWidth; height: grid.cellHeight
            Column {
                anchors.fill: parent
                Text { text: model.number; anchors.horizontalCenter: parent.horizontalCenter }
                Button{text: "change me"; onClicked: model.number +=1}
                Button{text: "change all"; onClicked: changeAll()}
            }
        }
    }
    Component.onCompleted: {
        for(var i=0; i < 10; ++i){
            listmodel.append({"number": 0});
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...