Qml:如何为所有 GridView 项目设置 属性

Qml: How to set a property to all GridView items

我正在尝试更改 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();
                        }
                    }
                }
            }
        }
    }
}

你的做法恰恰相反:你的做法是获取视图的item并进行修改,而Qt指出的做法是视图反映了模型的信息,在需要的时候进行修改。

下面是一个简单的例子,每次你按下带有 "change me" 文本的按钮增加它显示的数字,但是如果你按下带有 "change all" 文本的按钮它会改变所有的数字。据观察,一切都是通过模型完成的,而不是通过仅用于显示信息或接收用户交互的视图。

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