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 Updated to NodeBB v4.3 + New Features

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 1 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.
  • 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