【问题标题】:Qml: How to set a property to all GridView itemsQml:如何为所有 GridView 项目设置属性
【发布时间】:2020-01-28 17:12:18
【问题描述】:

我正在尝试更改 GridView 的所有项目。
我尝试遍历模型或网格,我在网上查看了类似的示例,但我尝试的所有内容都以Cannot read property 'buttonText' of undefined 结尾。

在我看来,问题在于解释器无法确定网格或模型中的项目是Button。但我不知道如何投射它。

如果我将日志更改为仅显示项目,而不显示任何属性(参见代码 sn-p),它似乎知道它是一个项目...请参阅下面的实验。

我唯一能做的就是从委托中设置一个属性(或调用一个信号或一个函数)。但这只会影响一个网格项目,而不是全部。

如何为网格的每个项目设置属性?或者,如何在每个项目上发送信号或调用函数?

我的实验在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();
                        }
                    }
                }
            }
        }
    }
}

【问题讨论】:

  • 您的问题不清楚,您的大部分问题都在抱怨“您可能的解决方案”,这显然不是正确的,您的具体目标是什么?您指出如何在每个按钮上设置属性?这是抽象的,所以我的问题是:您要具体修改什么属性?
  • 我想在网格的每个项目上设置一个属性。我打电话给他们Button。我没有“可能的解决方案” - 我在 for 循环中进行了实验,迭代了网格或模型 - 在每次尝试中,当我在项目后面加上一个属性名称时,我得到 undefined . @eyllanesc
  • 尝试是“可能的解决方案”。我的批评是,在您的大部分帖子中,您都专注于您的尝试,而没有首先指出您的具体目标是什么,例如,更清楚的是:我想修改以下代码中显示的元素 Y 的属性 X,以让我尝试过 P、Q 和 R,但我遇到了这些问题。好吧,绕过我已经发布了一个说明性示例。
  • @eyllanesc 谢谢,为我辩护,我想做的是修改所有项目的任何属性,以便在项目中我可以使用函数onPropertyChanged - 因为这是唯一的方法我发现向所有项目发出信号。

标签: qt gridview qml


【解决方案1】:

你的做法是相反的:你的做法是获取视图的item并修改它,但是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});
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 1970-01-01
    • 2020-02-09
    • 2017-02-27
    • 1970-01-01
    相关资源
    最近更新 更多