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. Add item to ListModel at run-time
Forum Updated to NodeBB v4.3 + New Features

Add item to ListModel at run-time

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
4 Posts 2 Posters 1.4k 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.
  • Q Offline
    Q Offline
    qcoderpro
    wrote on last edited by
    #1

    Hi all,

    Here's a simplified version of a bigger code:

    import QtQuick
    import QtQuick.Controls
    
    Window {
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
        
        Column {
            spacing: 10
            Button {
                text: qsTr("Add Item")
                font.pixelSize: 15
                onClicked: listMd.append({
                                             "name": txtField.text
                                             triggered: function() { console.log("One") }
                                         })
            }
            
            TextField {
                id: txtField
            }
        }
        
        Rectangle {
            id: root
            anchors.centerIn: parent
            width: 200; height: 150
            color: "lightblue"
            
            ListModel {
                id: listMd
                ListElement {
                    name: qsTr("One")
                    triggered: function() { console.log("One") }
                }
                ListElement {
                    name: qsTr("Two")
                    triggered: function() { console.log("Two") }
                }
            }
            
            Component {
                id: nameDelegate
                
                Text {
                    text: model.name
                    font.pixelSize: 32
                    
                    MouseArea {
                        anchors.fill: parent
                        onClicked: model.triggered()
                    }
                }
            }
            
            ListView {
                id: lsView
                anchors.fill: parent
                model: listMd
                delegate: nameDelegate
                clip: true
                focus: true
            }
        }
    }
    

    I've got two questions:

    1. How to modify the list elements so that the console.log function prints the name of the element? I tried:
    ListElement {
                    name: qsTr("One")
                    triggered: function() { console.log(model.name) }
                }
    

    But I get this error: ReferenceError: model is not defined

    1. How to add and new element using the button and text field in the code please? I tried using append() but it's not working properly.
    1 Reply Last reply
    0
    • fcarneyF Offline
      fcarneyF Offline
      fcarney
      wrote on last edited by fcarney
      #2

      @qcoderpro said in Add item to ListModel at run-time:

      How to modify the list elements so that the console.log function prints the name of the element? I tried:

                  ListElement {
                      name: qsTr("One")
                      triggered: function() { console.log(name) }
                  }
      

      What happens if you put triggered in quotes?

      onClicked: listMd.append({
                                               "name": txtField.text
                                               "triggered": function() { console.log("One") }
                                           })
      

      Are you getting any console errors?

      https://doc.qt.io/qt-5/qml-qtqml-models-listmodel.html#append-method
      It shows field names in quotes. The quotes seem kinda odd to me.

      C++ is a perfectly valid school of magic.

      Q 1 Reply Last reply
      1
      • fcarneyF fcarney

        @qcoderpro said in Add item to ListModel at run-time:

        How to modify the list elements so that the console.log function prints the name of the element? I tried:

                    ListElement {
                        name: qsTr("One")
                        triggered: function() { console.log(name) }
                    }
        

        What happens if you put triggered in quotes?

        onClicked: listMd.append({
                                                 "name": txtField.text
                                                 "triggered": function() { console.log("One") }
                                             })
        

        Are you getting any console errors?

        https://doc.qt.io/qt-5/qml-qtqml-models-listmodel.html#append-method
        It shows field names in quotes. The quotes seem kinda odd to me.

        Q Offline
        Q Offline
        qcoderpro
        wrote on last edited by qcoderpro
        #3

        @fcarney

        Are you getting any console errors?

        Yes, I get Expected token '}' error for the line triggered!

        I tried this:

        // ...
        Button {
                    text: qsTr("Add Item")
                    font.pixelSize: 15
        
                    onClicked: listMd.append(
                                   {
                                       name: txtField.text,
                                       triggered: function() { console.log("new Item") }
                                   })
                }
        // ...
        

        When I type "Three" in the text field and click on Add Item the text will be added to the list, but I also get the error: <Unknown File>: Can't assign to existing role 'triggered' of different type [VariantMap -> Function]

        fds.PNG

        1 Reply Last reply
        0
        • fcarneyF Offline
          fcarneyF Offline
          fcarney
          wrote on last edited by
          #4

          @qcoderpro said in Add item to ListModel at run-time:

          Can't assign to existing role 'triggered' of different type [VariantMap -> Function]

          It is seeing the ListElement "triggered" as something different than the append version of "triggered". So a work around is to add the initial elements via Component.onCompleted:

          import QtQuick 2.15
          import QtQuick.Controls 2.15
          import QtQuick.Window 2.15
          
          Window {
              width: 640
              height: 480
              visible: true
              title: qsTr("Hello World")
          
              Column {
                  spacing: 10
                  Button {
                      text: qsTr("Add Item")
                      font.pixelSize: 15
                      onClicked: listMd.append({
                          name: txtField.text,
                          triggered: function() { console.log(txtField.text) }
                      })
                  }
          
                  TextField {
                      id: txtField
                  }
              }
          
              Rectangle {
                  id: root
                  anchors.centerIn: parent
                  width: 200; height: 150
                  color: "lightblue"
          
                  ListModel {
                      id: listMd
                      /*
                      ListElement {
                          name: qsTr("One")
                          triggered: function() { console.log("One") }
                      }
                      ListElement {
                          name: qsTr("Two")
                          triggered: function() { console.log("Two") }
                      }
                      */
                      Component.onCompleted: {
                          listMd.append({ name: "One", triggered: function() { console.log("One") }})
                          listMd.append({ name: "Two", triggered: function() { console.log("Two") }})
                      }
                  }
          
                  Component {
                      id: nameDelegate
          
                      Text {
                          text: model.name
                          font.pixelSize: 32
          
                          MouseArea {
                              anchors.fill: parent
                              onClicked: model.triggered()
                          }
                      }
                  }
          
                  ListView {
                      id: lsView
                      anchors.fill: parent
                      model: listMd
                      delegate: nameDelegate
                      clip: true
                      focus: true
                  }
              }
          }
          

          When clicking the text it does not run the function:
          qrc:/main.qml:62: TypeError: Property 'triggered' of object QQmlDMAbstractItemModelData(0x55ed97edb360) is not a function
          The conversion of the object in append is turning the function into an object of some type. I have seen ListModel convert other objects before when using append. So I don't think this approach will work this way.

          You could insert a string for the triggered property. Then use that string to lookup the function you want to call. You could store the function lookup object anywhere. The problem is now you have 2 lists. So maybe that isn't a good solution.

          (For the future, when posting minimal code, please check that it runs. There was stuff missing in the first post.)

          C++ is a perfectly valid school of magic.

          1 Reply Last reply
          1

          • Login

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