Mohan S
Mohan S

Reputation: 11

Repeater Delegate not access the properties from list model

From this link described the Repeater problem.

@Stephen Quan, As per your suggestion modified code to ListModel.

ListModel {
     id:listModel 
}

function handleModelChanged() {
    delegateModel.model = areaViewModel;
    const newUiType = areaViewModel.uiType;

    if (newUiType !== uiType || !modelDataIsEqual(delegateModel, listModel) ) { 
        listModel.clear();
        dlaButtonStyle = areaModel.combineBtnStyle;
        oddEvenBtnAppearance = areaModel.getLockedButtonAppearance();

        for (var row = 0; row < delegateModel.model.rowCount(); row++) {
            var item = delegateModel.items.get(row).model;
            var button = dataModelItemToButton(item);                 
            listModel.append(button);
        } 
        
        console.log(listModel.get(0).dataAreaName);
        uiType = newUiType;
    } else {
        console.log("GRID buttons are same")
    }
}

Repeater {
    id: areaRepeater
    model: listModel

    delegate: {
        gridButton;
    }
    onItemAdded: {              
        if (index == areaRepeater.count - 1) {
            console.log("GRID repeater added " + areaRepeater.count + " buttons")
            updateItems()
        }
    }
}

But, I got this output when expose this listmodel in repeater:

But our expected result is:

without changing old code

I thought item properties not set properly in delegate. Where I made mistake in my code. Kindly, help to resolve it.

Thanks Advance

Upvotes: 0

Views: 197

Answers (1)

Stephen Quan
Stephen Quan

Reputation: 26299

When switching from Javascript model to ListModel be aware that your delegate bindings changes from modelData.property to model.property or even property.

The other concern I have with your code is it appears that you're trying to dynamically create QML components using QML code. You should declare your delegates declarative and let Qt take care of the delegate construction and destructor for you.

The following demonstrates a simpler approach to populating GridView ListModel. Note that you do not need to constantly reassign the GridView.model, we set it once, and, after that, we just append directly to the ListModel.

In the following we are 'slowly' populating the ListModel with 100000 records. You should observe that there is no exponential slowdown. The latter records are being inserted at a similar speed as the first records were. Also note that the populating of the ListModel automatically creates new delegates. Likewise, changes or deletions to the ListModel will also automatically update the delegates.

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
    background: Rectangle { color: "black" }
    GridView {
        anchors.fill: parent
        model: ListModel { id: listModel }
        clip: true
        cellWidth: 100
        cellHeight: 100
        delegate: Item {
            width: 100
            height: 100
            Rectangle {
                anchors.fill: parent
                anchors.margins: 4
                border.color: "white"
                border.width: 2
                radius: 10
                color: "black"
                Text {
                    anchors.centerIn: parent
                    text: num
                    color: "white"
                    font.pointSize: 30
                    font.bold: true
                }
            }
        }
        ScrollBar.vertical: ScrollBar {
            width: 20
            policy: ScrollBar.AlwaysOn
        }
    }
    Timer {
        interval: 1
        running: appendRadio.checked && listModel.count < 100000
        onTriggered: listModel.append( { num: Math.floor(Math.random() * 100) } )
    }
    Timer {
        interval: 1
        running: removeRadio.checked && listModel.count > 0
        onTriggered: listModel.remove(0)
    }
    footer: Frame {
        background: Rectangle { color: "#eee" }
        RowLayout {
            Text {
                text: "Count: %1".arg(listModel.count)
            }
            RadioButton {
                id: appendRadio
                checked: true
                text: "ListModel.Append"
            }
            RadioButton {
                id: removeRadio
                text: "ListModel.Remove"
            }
            Button {
                text: "Clear"
                onClicked: listModel.clear()
            }
        }
    }
}

You can Try it Online!

ListModelDemo.gif

Upvotes: 2

Related Questions