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

ListView(s) not updating when model-data changes



  • Hello everyone,

    I am currently using two separate ListViews that display data from the same ListModel. Every ListView has its own delegate. One ListView is supposed to be a device "overview", with the second ListView being the settings window.
    The ListModel is currently filled with dummy-data. The items have names, an ip-adress and so on. When I change the model data from one ListView, e.g. change the name, I cant get the other ListView to react to the change. Furthermore when I append items from the list or delete some the other ListView does not reflect the change but rather keeps on using the "deleted" item. The changes I make inside one ListView are updated immediately and without error.

    Is storing the data in a ListModel qml-file the wrong way to go?

    Thanks for the help.



  • @FrecciaGLT please provide a minimal and reproducible example



  • @eyllanesc
    main.qml

    import QtQuick 2.7
    import QtQuick.Controls 2.4
    import QtQuick.Controls.Material 2.4
    import QtQuick.Layouts 1.11
    import QtQuick.Window 2.11
    import QtQuick.LocalStorage 2.0
    
    Window {
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
    
        SwipeView {
            id: view
            currentIndex: 0
            anchors.fill: parent
            Item {
                id: firstPage
    
                    ListView {
                       id: plugListView
                       model: PlugModel {}
                       delegate: PlugDelegate {}
                       anchors.fill: parent
                       }
                    PlugDialog {
                       id: plugDialog
                       x: Math.round((parent.width - width) / 2)
                       y: Math.round((parent.height - height) / 2)
                       plugModel: plugListView.model
                    }
                    RoundButton {
                        id: addplugButton
                        text: "+"
                        anchors.bottom: parent.bottom
                        anchors.bottomMargin: 16
                        anchors.horizontalCenter: parent.horizontalCenter
                        onClicked: plugDialog.open()
                       }
         }
            Item {
                id: secondPage
                   ListView {
                        id: settingsView
                        model: PlugModel {}
                        delegate: SettingsDelegate {}
                        anchors.fill: parent
                    }
                }
    }
    }
    

    PlugModel.qml

    import QtQuick 2.13
    
    ListModel {
        id: plugModel
        ListElement {
            name: "Test plug"
            ipadr: "192.168.1.1"
        }
    }
    

    Delegate 1 - PlugDelegate.qml

    import QtQuick 2.9
    import QtQuick.Controls 2.4
    import QtQuick.Controls.Material 2.4
    import QtQuick.Layouts 1.11
    import QtQuick.Window 2.11
    import QtGraphicalEffects 1.0
    
    ItemDelegate {
        id: root
        width: parent.width
        checkable: true
        onClicked: ListView.view.currentIndex = index
    
                 Label {
                     id: nameLabel
                     font.pixelSize: Qt.application.font.pixelSize * 2
                     text: model.name
                    }
      }
    

    Delegate 2 - SettingsDelegate.qml

    import QtQuick 2.11
    import QtQuick.Controls 2.4
    import QtQuick.Controls.Material 2.4
    import QtQuick.Layouts 1.11
    import QtQuick.Window 2.11
    import QtGraphicalEffects 1.0
    
    ItemDelegate {
        id: root
        width: parent.width
        checkable: true
    
        onClicked: ListView.view.currentIndex = index
        property PlugModel plugModel
    
                Label {
                    id: nameLabel
                    font.pixelSize: Qt.application.font.pixelSize * 2
                    text: model.name
                }
                ColumnLayout {
                    spacing: 0
                    RowLayout {
                TextField {
                    id: settingsNameField
                    placeholderText: qsTr("Enter new name...")
                    cursorVisible: true
                    visible: root.checked
                }
                Button {
                    id: changeNameButton
                    text: qsTr("Change name")
                    width: 40
                    height: 20
                    visible: root.checked
                    onClicked: { model.name = settingsNameField.text }                              
                    }
                  }
                }
     }
    
    

    PlugDialog.qml

    import QtQuick 2.11
    import QtQuick.Controls 2.4
    import QtQuick.Layouts 1.11
    import QtQuick.Window 2.11
    
    Dialog {
        id: plugDialog
        title: "Add new plug"
        width: 200
        height: 200
        modal: true
        standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel
    
        property PlugModel plugModel
    
        TextField {
            Layout.fillWidth: true
            anchors.left: parent.left
            id: plugDescriptionTextField
            width: 150
            placeholderText: qsTr("Enter plug name...")
            cursorVisible: true
            visible: plugModel.checked
            text: PlugModel.name
            onTextEdited: PlugModel.name = text
        }
        TextField {
            Layout.fillWidth: true
            anchors.top: plugDescriptionTextField.bottom
            id: plugIpAdrTextField
            width: 150
            placeholderText: qsTr("Enter plug IpAdr...")
            cursorVisible: true
            visible: PlugModel.checked
            text: PlugModel.ipadr
            onTextEdited: PlugModel.ipadr = text
        }
        onAccepted: {
               plugModel.append({
               "name": plugDescriptionTextField.text,
               "ipadr": plugIpAdrTextField.text,
            })
    
        }
        onRejected: plugDialog.close()
    

    As you can see, when adding a new device on page 1 or changing the device name on page 2 (after clicking on the name the box appears) the changes are not reflected in the other ListView.



  • @FrecciaGLT The problem is caused because you are creating 2 models, the solution is add in main.qml:

    PlugModel{
        id: the_unique_plugModel
    }
    

    And change for each ListView to:

    model: the_unique_plugModel
    

    and PlugDialog:

    plugModel: the_unique_plugModel
    


  • @eyllanesc
    Thank you very much, this solved the problem. The amount of time I spent on this issue and then having the error be such a trivial thing, great.

    -- marking this as solved


Log in to reply