Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Deleting items from primary ListModel
Forum Updated to NodeBB v4.3 + New Features

Deleting items from primary ListModel

Scheduled Pinned Locked Moved Solved QML and Qt Quick
13 Posts 4 Posters 1.7k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    The3DmaN
    wrote on last edited by The3DmaN
    #1

    I am working on a ListModel for rss feeds and need to be able to delete ListElements and eventually add items too. I am struggling to be able to properly implement this. When I run my RssEdit.ui.qml I am able to see the list of elements it gets from RssList.qml and have a remove button next to each item, however when I click the delete button it only seems to delete that element/item from the ListView in RssEdit.ui.qml and not the parent ListModel in RssList.qml. I have tried to implement many different ideas and I am stuck. Hoping someone can help with this one. How do I get my button to not only delete the current item from the current view, but also from the main ListModel in RssList.qml? Any assistance would be very much appreciated. I have been searching for similar stuff for days hoping to find an answer, and have not found anything I was able to get working.

    RssList.qml

    import QtQuick 2.0
    
    
    ListModel {
        ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
        ListElement { name: "New York Post"; feed: "nypost.com/feed" }
    }
    

    RssEdit.ui.qml

    import QtQuick 2.12
    import QtQuick.Controls 2.5
    
    Page {
    
        title: qsTr("Feeds")
    
        RssList { id: rssFeeds }
    
        ListView {
            id: listView
            anchors.fill: parent
            model: rssFeeds
            delegate: Item {
                x: 5
                width: 80
                height: 40
                Row {
                    id: row1
                    spacing: 10
                    Rectangle {
                        width: 40
                        height: 40
                        color: colorCode
                    }
    
                    Text {
                        text: name
                        anchors.verticalCenter: parent.verticalCenter
                        font.bold: true
                    }
    
                    Button {
                        id: deleterss
                        visible: true
                        text: "Delete From List"
                        display: AbstractButton.TextOnly
    
                        Connections {
                            target: deleterss
                            onClicked: {
                                rssFeeds.remove(index)
                            }
                        }
                    }
                }
            }
        }
    }
    
    
    B 1 Reply Last reply
    0
    • 6thC6 Offline
      6thC6 Offline
      6thC
      wrote on last edited by
      #2

      remove is correct, but I'm not sure that is how you'd get that ListModel... you could use an alias to expose it... for now, what about if you do, instead of:

      RssList { id: rssFeeds }
      

      use

      ListModel { id: rssFeeds;
          ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
          ListElement { name: "New York Post"; feed: "nypost.com/feed" }
      }
      

      Then does your remove work.

      T 1 Reply Last reply
      0
      • T The3DmaN

        I am working on a ListModel for rss feeds and need to be able to delete ListElements and eventually add items too. I am struggling to be able to properly implement this. When I run my RssEdit.ui.qml I am able to see the list of elements it gets from RssList.qml and have a remove button next to each item, however when I click the delete button it only seems to delete that element/item from the ListView in RssEdit.ui.qml and not the parent ListModel in RssList.qml. I have tried to implement many different ideas and I am stuck. Hoping someone can help with this one. How do I get my button to not only delete the current item from the current view, but also from the main ListModel in RssList.qml? Any assistance would be very much appreciated. I have been searching for similar stuff for days hoping to find an answer, and have not found anything I was able to get working.

        RssList.qml

        import QtQuick 2.0
        
        
        ListModel {
            ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
            ListElement { name: "New York Post"; feed: "nypost.com/feed" }
        }
        

        RssEdit.ui.qml

        import QtQuick 2.12
        import QtQuick.Controls 2.5
        
        Page {
        
            title: qsTr("Feeds")
        
            RssList { id: rssFeeds }
        
            ListView {
                id: listView
                anchors.fill: parent
                model: rssFeeds
                delegate: Item {
                    x: 5
                    width: 80
                    height: 40
                    Row {
                        id: row1
                        spacing: 10
                        Rectangle {
                            width: 40
                            height: 40
                            color: colorCode
                        }
        
                        Text {
                            text: name
                            anchors.verticalCenter: parent.verticalCenter
                            font.bold: true
                        }
        
                        Button {
                            id: deleterss
                            visible: true
                            text: "Delete From List"
                            display: AbstractButton.TextOnly
        
                            Connections {
                                target: deleterss
                                onClicked: {
                                    rssFeeds.remove(index)
                                }
                            }
                        }
                    }
                }
            }
        }
        
        
        B Offline
        B Offline
        Bob64
        wrote on last edited by Bob64
        #3

        @The3DmaN I am not sure what you mean when you say this: "it only seems to delete that element/item from the ListView in RssEdit.ui.qml and not the parent ListModel in RssList.qml". What is it that you are expecting to see? What are you doing in the rest of your code that makes you think it is not working properly?

        Based on what I can see and what you have described, it seems to be working correctly and I am wondering if you might have a conceptual misunderstanding. When you do this in your RssEdit.ui.qml:

             RssList {  id: rssFeeds }
        

        you are creating a new instance of the model. Generally speaking, unless you do extra work, it is only really going to be visible in the component where you create it. If you want to share the model with some other view, for example, you will have to do something like instantiating the model higher up and assigning it to properties of the views that need to access it.

        1 Reply Last reply
        1
        • 6thC6 6thC

          remove is correct, but I'm not sure that is how you'd get that ListModel... you could use an alias to expose it... for now, what about if you do, instead of:

          RssList { id: rssFeeds }
          

          use

          ListModel { id: rssFeeds;
              ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
              ListElement { name: "New York Post"; feed: "nypost.com/feed" }
          }
          

          Then does your remove work.

          T Offline
          T Offline
          The3DmaN
          wrote on last edited by The3DmaN
          #4

          @6thC I tried it the way you mention, and as @Bob64 stated maybe it's that I am not conceptually understanding how the ListModel works. Even when I try it this way while I am in the app on the RssEdit.ui.qml page, when I click remove, it removes it from the visual list in the running page only. As soon as I exit the page and come back or restart the app the list is right back to what it was before the item deleted. Its like it never happened.

          I guess my thought was that if I were to delete say the NY Post entry with the delete button, on the back end the list would go from

          This:

          ListModel { id: rssFeeds;
              ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
              ListElement { name: "New York Post"; feed: "nypost.com/feed" }
          }
          

          To This:

          ListModel { id: rssFeeds;
              ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
          }
          

          so that when I went back to the page or restarted the app, the list would retain the delete, but that does not seem to be happening.

          B 1 Reply Last reply
          0
          • CharbyC Offline
            CharbyC Offline
            Charby
            wrote on last edited by
            #5

            @The3DmaN here is a working code snipped showing adding and removing news feed. (btw you might be interested in XmlListModel instead of ListModel )

            import QtQuick 2.12
            import QtQuick.Window 2.12
            import QtQuick.Controls 2.12
            import QtQuick.Layouts 1.12
            Window {
                width: 640; height: 480; visible: true; title: qsTr("Hello World")
            
                ListModel {
                    id:theModel
                    ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
                    ListElement { name: "New York Post"; feed: "nypost.com/feed" }
                }
                ListView{
                    id:theView
                    anchors.fill:parent
                    anchors.bottomMargin: addPanel.height
                    model:theModel
                    delegate:RowLayout{
                        width : theView.width
                        Label{ text:name}
                        Label{ text:feed; Layout.fillWidth: true}
                        Button{ text:"-"; onClicked: theModel.remove(index)}
            
                    }
                }
                RowLayout{
                    id:addPanel
                    anchors.top: theView.bottom
                    width : theView.width
                    TextEdit{ id: newSource; text:"source"}
                    TextEdit{ id: newFeed; text:"feed"; Layout.fillWidth: true}
                    Button{ text:"+"; onClicked: theModel.append({ name: newSource.text, feed: newFeed.text })}
                }
            
            }
            
            
            T 1 Reply Last reply
            0
            • T The3DmaN

              @6thC I tried it the way you mention, and as @Bob64 stated maybe it's that I am not conceptually understanding how the ListModel works. Even when I try it this way while I am in the app on the RssEdit.ui.qml page, when I click remove, it removes it from the visual list in the running page only. As soon as I exit the page and come back or restart the app the list is right back to what it was before the item deleted. Its like it never happened.

              I guess my thought was that if I were to delete say the NY Post entry with the delete button, on the back end the list would go from

              This:

              ListModel { id: rssFeeds;
                  ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
                  ListElement { name: "New York Post"; feed: "nypost.com/feed" }
              }
              

              To This:

              ListModel { id: rssFeeds;
                  ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
              }
              

              so that when I went back to the page or restarted the app, the list would retain the delete, but that does not seem to be happening.

              B Offline
              B Offline
              Bob64
              wrote on last edited by Bob64
              #6

              @The3DmaN OK, I think I understand what you are observing a bit better now. The issue is that if you leave the page after deleting an item, the deleted item has reappeared when you revisit the page. Correct?

              If that is the case, it sounds to me as if your page must be being recreated each time you open it. If that were the case, because the model is scoped to the page, it also would be recreated, so it would appear to be back in its initial state.

              How are you instantiating your Page objects? Are you using createObject anywhere or anything like that?

              1 Reply Last reply
              0
              • CharbyC Charby

                @The3DmaN here is a working code snipped showing adding and removing news feed. (btw you might be interested in XmlListModel instead of ListModel )

                import QtQuick 2.12
                import QtQuick.Window 2.12
                import QtQuick.Controls 2.12
                import QtQuick.Layouts 1.12
                Window {
                    width: 640; height: 480; visible: true; title: qsTr("Hello World")
                
                    ListModel {
                        id:theModel
                        ListElement { name: "CNN"; feed: "news.yahoo.com/rss/world" }
                        ListElement { name: "New York Post"; feed: "nypost.com/feed" }
                    }
                    ListView{
                        id:theView
                        anchors.fill:parent
                        anchors.bottomMargin: addPanel.height
                        model:theModel
                        delegate:RowLayout{
                            width : theView.width
                            Label{ text:name}
                            Label{ text:feed; Layout.fillWidth: true}
                            Button{ text:"-"; onClicked: theModel.remove(index)}
                
                        }
                    }
                    RowLayout{
                        id:addPanel
                        anchors.top: theView.bottom
                        width : theView.width
                        TextEdit{ id: newSource; text:"source"}
                        TextEdit{ id: newFeed; text:"feed"; Layout.fillWidth: true}
                        Button{ text:"+"; onClicked: theModel.append({ name: newSource.text, feed: newFeed.text })}
                    }
                
                }
                
                
                T Offline
                T Offline
                The3DmaN
                wrote on last edited by The3DmaN
                #7

                @Charby Isn't XmlListModel for read only models? I tested out your code above, and it has the same issue as mine. When clicking remove in the running app, it removes it while running the app, but as soon as you reopen the app the item removed is back. Where I am struggling is how to update the actual ListModel with the change so that when you reopen the app or page the item removed is still gone.

                @Bob64 You are correct in your assumptions. I am not using createObject anywhere that I know of. I uploaded my full original project to Gitlab (this was my code before making any suggested changes from here) if that helps with the analysis, but it is pretty basic so far. Just a generic Qt Quick StackView template as its base with only 2 pages and 1 ListModel qml. My main goal is to be able to edit the list of rss feeds so that I can then use that to pull feeds from those sites and display them on the currently blank DisplayFeed.ui.qml page in the future. Pulling the feeds and displaying them is not an issue, I have done that before, I am just stuck figuring out how to implement the user editable list of feeds and have it stick on re-opening of the app/page.

                Gitlab: https://gitlab.com/The3DmaN/rss-feed

                The only change I have made to the gitlab original code is I moved the ListModel from its own RssList.qml file to being directly in the RssEdit.ui.qml page so that I was not creating a full new instance of the model with " RssList { id: rssFeeds }" as I was informed of above, however, I am wondering if I should keep it in its own qml since I will eventually need to pull this list model in other pages for displaying the feeds. My apologizes for my inexperience with all of this. I appreciate all the help and guidance.

                1 Reply Last reply
                0
                • CharbyC Offline
                  CharbyC Offline
                  Charby
                  wrote on last edited by
                  #8

                  as @Bob64 pointed out, what you are experiencing is a normal behavior of the stackview recreating when requested the RssEdit.ui.qml page. As the list model is part of the page, it will be recreated with its default each time the page is loaded.

                  Here are a few options you could follow :

                  • the easiest (Quick & dirty) : move the ListModel at the root of main QML, give it a unique id name, and use this id in from RssEdit.ui.qml.
                  • same but cleaner : same as before but instead of using the id directly from RssEdit.ui.qml, create a property in RssEdit.ui.qml that will be list model to use. In main.qml this property will be affected with your actual ListModel
                  • put your list model in a singleton so it could be used wherever you want
                  1 Reply Last reply
                  0
                  • CharbyC Offline
                    CharbyC Offline
                    Charby
                    wrote on last edited by
                    #9

                    From your edited last post I now understand you also want the list model content to be persisting after the lifetime of your application.
                    In that case, you will in addition need to take care of this persisting state (saving when the app quit, loading when the app start) somewhere (a file, a database...)

                    T 1 Reply Last reply
                    0
                    • CharbyC Charby

                      From your edited last post I now understand you also want the list model content to be persisting after the lifetime of your application.
                      In that case, you will in addition need to take care of this persisting state (saving when the app quit, loading when the app start) somewhere (a file, a database...)

                      T Offline
                      T Offline
                      The3DmaN
                      wrote on last edited by
                      #10

                      @Charby So it sounds like I will need to create an actual XML or database file and then have the app edit that file directly. Thank you, I will give this a shot. I think my misunderstanding was me assuming changes to a ListModel would be persistent after the lifetime of the app. I will mark this as solved since my main question was answered.

                      1 Reply Last reply
                      0
                      • CharbyC Offline
                        CharbyC Offline
                        Charby
                        wrote on last edited by
                        #11

                        @The3DmaN creating a xml file or a database file are not the only options. You could for instance rely on QSettings for the persisting of the ListModel.

                        T 1 Reply Last reply
                        0
                        • CharbyC Charby

                          @The3DmaN creating a xml file or a database file are not the only options. You could for instance rely on QSettings for the persisting of the ListModel.

                          T Offline
                          T Offline
                          The3DmaN
                          wrote on last edited by
                          #12

                          Thank you @Charby I will have a look at that option too. Much appreciated.

                          1 Reply Last reply
                          0
                          • CharbyC Offline
                            CharbyC Offline
                            Charby
                            wrote on last edited by
                            #13

                            @The3DmaN The following code shows how to use a Settings to keep the feeds sources after apps lifetime

                            import QtQuick 2.12
                            import Qt.labs.settings 1.0
                            import QtQuick.Controls 2.12
                            import QtQuick.Layouts 1.12
                            import QtQuick.XmlListModel 2.12
                            
                            ApplicationWindow {
                                width: 640; height: 480; visible: true; title: qsTr("News reader")
                            
                                // The list of feeds sources (static content is only used if persisting is not available
                                ListModel {
                                    id:rssFeeds
                                    ListElement { name: "CNN"; feed: "http://news.yahoo.com/rss/world"; colorCode:"blue"}
                                    ListElement { name: "New York Post"; feed: "http://nypost.com/news/feed"; colorCode:"green" }
                            
                                }
                            
                                // Load the feeds sources at startup
                                Component.onCompleted: {
                                    var tmpArray =[];
                                    tmpArray = JSON.parse(settings.rssFeedsSavedAsString)
                                    if (tmpArray.length !== 0)
                                        rssFeeds.clear();
                                    for (var i = 0; i < tmpArray.length; ++i)
                                        rssFeeds.append(tmpArray[i])
                                }
                            
                                // Have the feeds source persisting after app lifetime
                                onClosing: {
                                    var tmpArray =[];
                                    for (var i = 0; i < rssFeeds.count; ++i)
                                        tmpArray.push(rssFeeds.get(i));
                                    settings.rssFeedsSavedAsString = JSON.stringify(tmpArray)
                                }
                            
                                // The serialized string used for persisting the feeds sources
                                Settings{
                                    id:settings
                                    property string rssFeedsSavedAsString : ""
                                }
                            
                                // The selected feed
                                XmlListModel{
                                    id:feedContent
                                    source: rssFeeds.get(feedsSelector.currentIndex).feed
                                    query: "/rss/channel/item"
                                    XmlRole { name:"title"; query: "title/string()"}
                                }
                            //The 3 UI elements : selection of feeds, selected feed content and control panel
                            
                                ColumnLayout{
                                    anchors.fill:parent; anchors.margins: 5
                                    ListView{
                                        id:feedsSelector
                                        currentIndex: 0
                                        Layout.fillWidth: true
                                        Layout.fillHeight: true
                                        model:rssFeeds
                                        highlight:Rectangle{ color: "lightblue"}
                                        delegate:RowLayout{
                                            width : feedsSelector.width
                                            Label{ text:name; color:colorCode; MouseArea{ anchors.fill:parent; onClicked: feedsSelector.currentIndex = index}}
                                            Label{ text:feed; Layout.fillWidth: true; MouseArea{ anchors.fill:parent; onClicked: feedsSelector.currentIndex = index}}
                            
                                            Button{ text:"-"; onClicked: rssFeeds.remove(index)}
                            
                                        }
                                    }
                                    ListView{
                                        Layout.fillWidth: true
                                        Layout.fillHeight: true
                                        model:feedContent
                                        delegate:RowLayout{
                                            width : feedsSelector.width
                                            Label{ text:title; color:rssFeeds.get(feedsSelector.currentIndex).colorCode}
                                        }
                                    }
                                    RowLayout{
                                        id:addPanel
                                        Layout.fillWidth: true
                                        Layout.fillHeight: true
                                        TextEdit{ id: newSource; text:"BBC"}
                                        TextEdit{ id: newFeed; text:"http://feeds.bbci.co.uk/news/world/rss.xml"; Layout.fillWidth: true}
                                        Button{ text:"+"; onClicked: rssFeeds.append({ name: newSource.text, feed: newFeed.text, colorCode:"orange" })}
                                    }
                                }
                            }
                            
                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved