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