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. How to append function object to an ListElement and callback when the element clicked
Forum Update on Monday, May 27th 2025

How to append function object to an ListElement and callback when the element clicked

Scheduled Pinned Locked Moved QML and Qt Quick
12 Posts 2 Posters 6.9k Views
  • 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.
  • S Offline
    S Offline
    story1225
    wrote on last edited by
    #1

    Like 'LauncherList' in Qt5.3 examples, I defined a common listview just replacing the url in function 'addExample' with a callback function object. In Component.onCompleted, use addExample to set every element's callback while clicked.
    I wanted the callback object can be called when list element clicked, but it was failed. After the callback function object append to listElement, its type was 'object', not 'function' anymore. How can I call the callback object?
    Thanks a lot!

    1 Reply Last reply
    0
    • D Offline
      D Offline
      dasRicardo
      wrote on last edited by
      #2

      If i understand it right, you have a model where you store a function in a key. Now you want to execute this function if you click on an element? For this you can use the "call":https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call function of javascript.

      **Sorry for my english :)

      PLEASE ADD [SOLVED] TO YOUR THREAD TITLE IF IT'S SOLVED.**

      1 Reply Last reply
      0
      • S Offline
        S Offline
        story1225
        wrote on last edited by
        #3

        Thanks for replay!
        I think I did not use model to store function with keys.
        I just want to use it like this,

        @Item {
        height: 480
        width: 320
        LauncherList {
        id: ll
        anchors.fill: parent

            function callback1(){}
            function callback2(){}
        
            Component.onCompleted: {
                addExample("Hello1",callback1)       addExample("Hello2",callback2)
            }
        }
        

        }@

        But after pass callback1/2 to the ListElement, its type was 'object', not 'function' any more, so calling was failed

        1 Reply Last reply
        0
        • D Offline
          D Offline
          dasRicardo
          wrote on last edited by
          #4

          In JavaScript everything is an object. You can use the call function for that like i wrote in my first answer. object.call(); Please take a look into the documentation.

          **Sorry for my english :)

          PLEASE ADD [SOLVED] TO YOUR THREAD TITLE IF IT'S SOLVED.**

          1 Reply Last reply
          0
          • S Offline
            S Offline
            story1225
            wrote on last edited by
            #5

            OK, I try it. Thanks. :)

            1 Reply Last reply
            0
            • S Offline
              S Offline
              story1225
              wrote on last edited by
              #6

              Hi, I failed to resolved this problem at last. :(
              Here is my test code,
              main.qml
              @import QtQuick 2.2
              import QtQuick.Controls 1.2

              ApplicationWindow {
              visible: true
              width: 480
              height: 640

              Rectangle {
                  anchors.fill: parent
                  color: "white"
              }
              
              Cmlist {
                  id: lst
                  anchors.fill: parent
              
                  Component.onCompleted: {
                      addItem("abc", callback1)
                      addItem("abc", callback1)
                  }
              
                  function callback1()
                  {
                      console.debug("callback1")
                  }
                  function callback2()
                  {
                      console.debug("callback2")
                  }
              }
              

              }@

              CmList.qml
              @import QtQuick 2.0

              Item {
              id: lst
              anchors.fill: parent

              ListModel {
                  id: lstmodel
              }
              
              Component {
                  id: lstdelegate
              
                  Rectangle {
                      id: lstitem
                      width: lst.width
                      height: 80
                      color: "steelblue"
              
                      Rectangle {
                          anchors.fill: parent
                          color: "#7A7A7A"
                          visible: mouse.pressed
                      }
              
                      Text {
                          id: lsttext
                          text: str
                          anchors.verticalCenter: parent.verticalCenter
                          anchors.left: parent.left
                          anchors.leftMargin: 10
                          font.pixelSize: parent.height * 0.5
                          font.bold: true
                          color: "black"
                      }
              
                      Rectangle {
                          height: 1
                          width: parent.width
                          color: "lightgray"
                          anchors.bottom: parent.bottom
                      }
              
                      signal clicked
                      onClicked: {
                          callback.call(this)
                      }
              
                      MouseArea {
                          id: mouse
                          anchors.left: parent.left
                          anchors.right: parent.right
                          anchors.top: parent.top
                          anchors.bottom: parent.bottom
                          onClicked: {
                              lstitem.clicked()
                          }
                      }
                  }
              }
              
              ListView {
                  id: lstview
                  anchors.fill: parent
                  model: lstmodel
                  delegate: lstdelegate
              }
              
              function addItem(str_, callback_)
              {
                  lstmodel.append({
                                      "str": str_,
                                      "callback": callback_
                                  })
              }
              

              }
              @

              when clicked item, it will print 'qrc:///Cmlist.qml:46: TypeError: Property 'call' of object [object Object] is not a function'.

              I am a newer at Qt and also not familiar with JavaScript.
              Is the calling 'callback.call(this)' wrong ?

              1 Reply Last reply
              0
              • D Offline
                D Offline
                dasRicardo
                wrote on last edited by
                #7

                Hmm, i don't see where you get the callback from the model?

                **Sorry for my english :)

                PLEASE ADD [SOLVED] TO YOUR THREAD TITLE IF IT'S SOLVED.**

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  story1225
                  wrote on last edited by
                  #8

                  At 'Component.onCompleted' in the main.qml, I pass the function reference 'callback1' to the ListElement renaming 'callback', see the addItem function in 'CmList.qml'.

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    dasRicardo
                    wrote on last edited by
                    #9

                    Hmm, you can try something like this:

                    @
                    import QtQuick 2.2
                    import QtQuick.Controls 1.2

                    ApplicationWindow {
                    visible: true
                    width: 480
                    height: 640

                    Rectangle {
                        anchors.fill: parent
                        color: "white"
                    }
                    
                    Cmlist {
                        id: lst
                        anchors.fill: parent
                    
                        Component.onCompleted: {
                            addItem(lst, "abc", "callback1")
                            addItem(lst, "abc", "callback2")
                        }
                    
                        function callback1()
                        {
                            console.debug("callback1")
                        }
                        function callback2()
                        {
                            console.debug("callback2")
                        }
                    }
                    

                    }
                    @

                    @
                    import QtQuick 2.0

                    Item {
                    id: lst
                    anchors.fill: parent

                    ListModel {
                        id: lstmodel
                    }
                    
                    Component {
                        id: lstdelegate
                    
                        Rectangle {
                            id: lstitem
                            width: lst.width
                            height: 80
                            color: "steelblue"
                    
                            Rectangle {
                                anchors.fill: parent
                                color: "#7A7A7A"
                                visible: mouse.pressed
                            }
                    
                            Text {
                                id: lsttext
                                text: str
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.left: parent.left
                                anchors.leftMargin: 10
                                font.pixelSize: parent.height * 0.5
                                font.bold: true
                                color: "black"
                            }
                    
                            Rectangle {
                                height: 1
                                width: parent.width
                                color: "lightgray"
                                anchors.bottom: parent.bottom
                            }
                    
                            signal clicked
                            onClicked: {
                                cmp.call(callback)
                            }
                    
                            MouseArea {
                                id: mouse
                                anchors.left: parent.left
                                anchors.right: parent.right
                                anchors.top: parent.top
                                anchors.bottom: parent.bottom
                                onClicked: {
                                    lstitem.clicked()
                                }
                            }
                        }
                    }
                    
                    ListView {
                        id: lstview
                        anchors.fill: parent
                        model: lstmodel
                        delegate: lstdelegate
                    }
                    
                    function addItem(cmp, str_, callback_)
                    {
                        lstmodel.append({
                            "cmp": cmp
                            "str": str_,
                            "callback": callback_
                        })
                    }
                    

                    }
                    @

                    You see the changes? The trick is to pass the object where the functions are defined (scope) to the model and use call with a string (the name of the function). You can also pass parameters. Everything after the function name will pass as parameter like: cmp.call(callback, param1, param2,...) I'm not at home so no guaranty :)

                    **Sorry for my english :)

                    PLEASE ADD [SOLVED] TO YOUR THREAD TITLE IF IT'S SOLVED.**

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      story1225
                      wrote on last edited by
                      #10

                      Thanks a lot! But it was not work correted. The error msg:

                      qrc:///Cmlist.qml:46: TypeError: Property 'call' of object Cmlist_QMLTYPE_0_QML_13(0x23ab3450) is not a function

                      I also try 'addItem(lst, "abc", callback1)', still it was not corrected.

                      1 Reply Last reply
                      0
                      • D Offline
                        D Offline
                        dasRicardo
                        wrote on last edited by
                        #11

                        Sorry my fault. The problem you have a Qml Object not a JavaScript object so no call function. Hmm, one solution can be to define the callback function in a JavaScript file. Like so:

                        @
                        // JS File

                        function callback1() { console.log("callback1");}
                        function callback2() { console.log("callback2");}

                        function callbackHandle(callback) { this.call(callback);}
                        @

                        @
                        import QtQuick 2.2
                        import QtQuick.Controls 1.2

                        ApplicationWindow {
                        visible: true
                        width: 480
                        height: 640

                        Rectangle {
                            anchors.fill: parent
                            color: "white"
                        }
                        
                        Cmlist {
                            id: lst
                            anchors.fill: parent
                        
                            Component.onCompleted: {
                                addItem("abc", "callback1")
                                addItem("abc", "callback2")
                            }
                        }
                        

                        }
                        @

                        @
                        import QtQuick 2.0
                        import "jsfile.js" as HANDLE

                        Item {
                        id: lst
                        anchors.fill: parent

                        ListModel {
                            id: lstmodel
                        }
                        
                        Component {
                            id: lstdelegate
                        
                            Rectangle {
                                id: lstitem
                                width: lst.width
                                height: 80
                                color: "steelblue"
                        
                                Rectangle {
                                    anchors.fill: parent
                                    color: "#7A7A7A"
                                    visible: mouse.pressed
                                }
                        
                                Text {
                                    id: lsttext
                                    text: str
                                    anchors.verticalCenter: parent.verticalCenter
                                    anchors.left: parent.left
                                    anchors.leftMargin: 10
                                    font.pixelSize: parent.height * 0.5
                                    font.bold: true
                                    color: "black"
                                }
                        
                                Rectangle {
                                    height: 1
                                    width: parent.width
                                    color: "lightgray"
                                    anchors.bottom: parent.bottom
                                }
                        
                                signal clicked
                                onClicked: {
                                    HANDLE.callbackHandler(callback)
                                }
                        
                                MouseArea {
                                    id: mouse
                                    anchors.left: parent.left
                                    anchors.right: parent.right
                                    anchors.top: parent.top
                                    anchors.bottom: parent.bottom
                                    onClicked: {
                                        lstitem.clicked()
                                    }
                                }
                            }
                        }
                        
                        ListView {
                            id: lstview
                            anchors.fill: parent
                            model: lstmodel
                            delegate: lstdelegate
                        }
                        
                        function addItem(str_, callback_)
                        {
                            lstmodel.append({
                                "str": str_,
                                "callback": callback_
                            })
                        }
                        

                        }
                        @

                        **Sorry for my english :)

                        PLEASE ADD [SOLVED] TO YOUR THREAD TITLE IF IT'S SOLVED.**

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          story1225
                          wrote on last edited by
                          #12

                          Thank you dasRicardo! but still has errors.
                          'qrc:///func.js:4: TypeError: Property 'call' of object [object Object] is not a function'

                          Now I used switch case to call different functions.
                          In
                          @signal clicked
                          onClicked: {
                          onElementClicked(callback_key)
                          }@
                          always call the same interface.
                          onElementClicked is defined at where I using the list view.

                          I just confused why some type like 'string' or 'int' can keep its real type after listview.append, but funtion type can not.

                          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