Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Gridview count and ListModel count not equal- Qt Bug?? Why?



  • After many hours of debugging I realized that for some unknown reason my GridView count and my ListModel count are not equal when I believe they should be. I am confused as to why they are not equal.

    Let me explain...I removed most of my code for conciseness...

    In the code I am using a ListModel as the model for the GridView. When I click the "add" button it should append a new Item to the ListModel, thereby creating a new delegate in the Gridview.

    The other button displays in the console the counts of the GridView and ListModel.

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtCharts 2.3
    import QtQuick.Controls 2.5
    
    Window {
        id: root
        visible: true
        width: 1200
        height: 800
        title: qsTr("GridViewDemo")
    
        property int numCharts: 0
    
        ListModel {
            id: modelId
        }
    
    
        Rectangle {
            id: rectId
            color: "pink"
            anchors.fill: parent
    
            GridView {
                id: mGridViewId
                anchors.fill: parent
                cellWidth: 300; cellHeight: 300
    
    
                model: modelId
    
                delegate: Rectangle {
                    id: rectDelegateContainerId
                    width: mGridViewId.cellWidth;
                    height: mGridViewId.cellHeight
                    color: "lightgrey"
                    border.color: "blue"
                    border.width: 2
                    radius: 2
                    property int myIndex: delegateIndex
    
                }
    
            }
        }
    
    
        Button {
            anchors.bottom: parent.bottom
            anchors.left: parent.left
            text: "add"
    
            onClicked: {
                modelId.append({'delegateIndex' : root.numCharts})
                root.numCharts++;
            }
        }
    
        Button {
            anchors.bottom: parent.bottom
            anchors.right: parent.right
            text: "display count"
    
            onClicked: {
                console.log("GridView Count: " + mGridViewId.contentItem.children.length);
                console.log("ListModel Count: " + modelId.count);
                console.log('===============================');
    
            }
        }
    }
    

    After launching the app the GridView and ListModel both have 0 items. (Click the "display count" button)

    After clicking the "add" button, one Item is appended to the ListModel. At that point, if you click the "display count" button, it will show the ListModel has one item, and the GridView has 2 items! Why? Is this a Qt bug?

    It only happens on the first append to the ListModel.

    Digging in further I realized the zeroth item, [0] in the GridView is the delegate created by appending to the ListModel, the [1] item in the GridView I am not sure what it is. It is an object of some kind...

    Any help is appreciated.
    Thanks

    P.S.
    This is affecting me because I am using the index of the ListModel the GridView to get the contextItem so I can get a reference to the dynamically created delegate Item.


  • Moderators

    It's not a bug. GridView can create as many children as it pleases. If you want to get the index of a delegate, just use the built-in index property. It's attached to each delegate. If you want to learn how many items are there in the GridView, use count method.



  • @sierdzio said in Gridview count and ListModel count not equal- Qt Bug?? Why?:

    GridView can create as man

    Thank you for your reply. The problem is the index of the ListModel I append and the index of the delegate are not going to be the same.

    In my case when I append an item to the listmodel, that index will be 0. A delegate will be created whose index will not be consistent with the ListModel's index.

    I found a workaround to this which seems kind of kludgy but apparently is the only way I can do it.

    No big deal its workable but it seems there should be a cleaner way. Thanks again.

    p.s. I found the workaround from SO here


  • Moderators

    Sorry we're either talking about 2 different topics or you are wrong. I took your code, used count and index as mentioned in my comment - it all works correctly. Counts are correct, children indexes are correct.

    I've added 3 items to model using the button, checked counts:

    qml: Index: 0
    qml: Index: 1
    qml: Index: 2
    qml: GridView Count: 3
    qml: ListModel Count: 3
    qml: ===============================
    

    Here's my slightly modified code:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    //import QtCharts 2.3
    import QtQuick.Controls 2.5
    
    Window {
        id: root
        visible: true
        width: 1200
        height: 800
        title: qsTr("GridViewDemo")
    
        property int numCharts: 0
    
        ListModel {
            id: modelId
        }
    
    
        Rectangle {
            id: rectId
            color: "pink"
            anchors.fill: parent
    
            GridView {
                id: mGridViewId
                anchors.fill: parent
                cellWidth: 300; cellHeight: 300
    
    
                model: modelId
    
                delegate: Rectangle {
                    id: rectDelegateContainerId
                    width: mGridViewId.cellWidth;
                    height: mGridViewId.cellHeight
                    color: "lightgrey"
                    border.color: "blue"
                    border.width: 2
                    radius: 2
                    property int myIndex: delegateIndex
                    Component.onCompleted: console.log("Index: " + index)
                }
    
            }
        }
    
    
        Button {
            anchors.bottom: parent.bottom
            anchors.left: parent.left
            text: "add"
    
            onClicked: {
                modelId.append({'delegateIndex' : root.numCharts})
                root.numCharts++;
            }
        }
    
        Button {
            anchors.bottom: parent.bottom
            anchors.right: parent.right
            text: "display count"
    
            onClicked: {
                console.log("GridView Count: " + mGridViewId.count);
                console.log("ListModel Count: " + modelId.count);
                console.log('===============================');
    
            }
        }
    }
    


  • What I am trying to express is that you cannot access the delegate by doing something similar to GridView.index and get the delegate.

    One has to loop through the GridView until we match the property of the index with the index of the listmodel item.

    It works thats all that matters now, thank you I sincerely appreciate you help. Cheers


  • Moderators

    Ah, right. That's because delegates are not meant to be accessed from the outside, the view can construct / destroy them without notice.


Log in to reply