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

Posted

技术标签:

【中文标题】Qml:如何为所有 GridView 项目设置属性【英文标题】:Qml: How to set a property to all GridView items 【发布时间】: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 - 因为这是唯一的方法我发现向所有项目发出信号。 【参考方案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 
                Buttontext: "change me"; onClicked: model.number +=1
                Buttontext: "change all"; onClicked: changeAll()
            
        
    
    Component.onCompleted: 
        for(var i=0; i < 10; ++i)
            listmodel.append("number": 0);
        
    

【讨论】:

以上是关于Qml:如何为所有 GridView 项目设置属性的主要内容,如果未能解决你的问题,请参考以下文章

如何为 QML 布局中的项目指定特定间距?

如何为我的 GridView 包含 SearchView?

如何为gridview项目(文本块)提供动态宽度?

QML - 如何适应和对齐 GridView 的项目?

如何为VS2013中的所有项目设置编译器警告级别?

如何为 GridView 中的特定行指定 CSS 类?