Home > Software design >  appending item into a listmodel which is in another file
appending item into a listmodel which is in another file

Time:10-17

My question is how can you append item coming from another listmodel.qml to another ListModel that is in another qml file.
There is a button in ItemDelegate from the NameDeleget.qml. when I click that button I want to append the name to the ListModel in favorite.qml.
When I push that favorite.qml into a StackView I want it to show the appended item.
Anyone with idea how to do that.

Home.qml

import QtQuick 2.0
import QtQuick.Controls 2.12

ApplicationWIndow {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    
    ListView {
        anchors.fill: parent
        model: NameModel{}
        delegate: NameDeleget{}
    }
}

NameModel.qml

import QtQuick 2.0

ListModel {
    listElement {name:""; value:}
    listElement {name:""; value:}
    listElement {name:""; value:}
}

NameDeleget.qml

import QtQuick 2.0
import QtQuick.Controls 2.12

ItemDelegate {
    width: parent.width
    text: model.name
    RoundButton {
        id: btn
        anchos.right: parent.right
        onclicked: {
        // When the button is clciked I want to append the clciked name to the "favorite.qml"
    }
}

Favorite.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import Qt.labs.settings 1.1
import Qt.labs.settings 1.0

Item {
    ListView {
        id: listView
        anchors.fill: parent

        model: ListModel {
            id: dataModel
            ListElement {name: "test1"; value: 1}
        }

        delegate: ItemDelegate {
            id: itemDelegete
            width: parent.width
            text: name  ":"  value
        }
    }
}

CodePudding user response:

I interpret your requirements as:

  • On HomePage.qml view ListModel containing names and pick your favourites
  • On FavouritePage.qml view the same ListModel but only show the selected favourites
  • Navigate between the two pages using StackView

So, to do this:

  • I ignored the requirement of two ListModel since only one ListModel is needed
  • Declare the ListModel in a parent scope so both pages can see it
  • Use DelegateModel on the second page to filter the records
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

Page {
    StackView {
        id: stackView
        anchors.fill: parent
        initialItem: "HomePage.qml"
    }
    ListModel {
        id: nameModel
        ListElement { name: "Steve Jobs"; fav: false }
        ListElement { name: "Bill Gates"; fav: false }
        ListElement { name: "Jeff Bezos"; fav: false }
    }
}

//HomePage.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Page {
    header: Frame {
        background: Rectangle { color: "lightgrey" }
        Text {
            text: "HomePage.qml (%1 total)".arg(nameModel.count)
        }
    }
    ListView {
        anchors.fill: parent
        model: nameModel
        delegate: Frame {
            background: Rectangle {
                color: (index & 1) ? "#f0f0f0" : "#e0e0e0"
            }
            width: ListView.view.width
            RowLayout {
                width: parent.width
                CheckBox {
                    checked: model.fav
                    onToggled: nameModel.setProperty(model.index, "fav", checked)
                }
                Text {
                    Layout.fillWidth: true
                    text: model.name
                }
            }
        }
    }
    footer: Button {
        text: "Goto Favourites"
        onClicked: stackView.push("FavouritePage.qml")
    }
}

//FavouritePage.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQml.Models 2.15
Page {
    header: Frame {
        background: Rectangle { color: "lightgrey" }
        Text {
            text: "FavouritePage.qml (%1 total)".arg(favourites.count)
        }
    }
    ListView {
        anchors.fill: parent
        model: FilterDelegateModel {
            id: favourites
            model: nameModel
            filter: e => e.fav
            delegate: Frame {
                background: Rectangle {
                    color: (index & 1) ? "#f0f0f0" : "#e0e0e0"
                }
                width: ListView.view.width
                RowLayout {
                    width: parent.width
                    Text {
                        Layout.fillWidth: true
                        text: model.name
                    }
                }
            }
        }
    }
    footer: Button {
        text: "Back to HomePage"
        onClicked: stackView.pop()
    }
}

//FilterDelegateModel.qml
import QtQuick 2.15
import QtQml.Models 2.15

DelegateModel {
    property var filter: null
    groups: [
        DelegateModelGroup {
            id: allItems
            name: "all"
            includeByDefault: true
            onCountChanged: Qt.callLater(update)
        },
        DelegateModelGroup {
            id: visibleItems
            name: "visible"
        }
    ]
    filterOnGroup: "visible"
    function update() {
        allItems.setGroups(0, allItems.count, [ "all" ] );
        for (let index = 0; index < allItems.count; index  ) {
            let item = allItems.get(index).model;
            let visible = !filter || filter(item);
            if (!visible) continue;
            allItems.setGroups(index, 1, [ "all", "visible" ]);
        }
    }
    Component.onCompleted: Qt.callLater(update)
}

You can e.fav delegate: Frame { background: Rectangle { color: (index & 1) ? "#f0f0f0" : "#e0e0e0" } width: ListView.view.width RowLayout { width: parent.width Text { Layout.fillWidth: true text: model.name } } } } } footer: Button { text: "Back to HomePage" onClicked: stackView.pop() } } //FilterDelegateModel.qml import QtQuick 2.15 import QtQml.Models 2.15 DelegateModel { property var filter: null groups: [ DelegateModelGroup { id: allItems name: "all" includeByDefault: true onCountChanged: Qt.callLater(update) }, DelegateModelGroup { id: visibleItems name: "visible" } ] filterOnGroup: "visible" function update() { allItems.setGroups(0, allItems.count, [ "all" ] ); for (let index = 0; index < allItems.count; index++) { let item = allItems.get(index).model; let visible = !filter || filter(item); if (!visible) continue; allItems.setGroups(index, 1, [ "all", "visible" ]); } } Component.onCompleted: Qt.callLater(update) } " rel="nofollow noreferrer">Try it Online!

  • Related