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. Can an onClicked() be a property?
Forum Updated to NodeBB v4.3 + New Features

Can an onClicked() be a property?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
20 Posts 7 Posters 1.4k Views 4 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.
  • JoeCFDJ JoeCFD

    @mzimmers
    override this func
    QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    then you can map QList to a QML ListView.

    piervalliP Offline
    piervalliP Offline
    piervalli
    wrote on last edited by
    #11

    @mzimmers

    QHash<int,QByteArray> roleNames() //mandatory for qml
    int rowCount

    Example
    https://stackoverflow.com/questions/44777999/manipulate-data-in-a-qabstractlistmodel-from-a-qml-listview

    1 Reply Last reply
    0
    • mzimmersM mzimmers

      Hi all -

      My app uses a customized list. Here's the minimum of it:

      // Roundlist.qml
      Rectangle { // list background
          property alias model: listView.model
          Component {
              id: listDelegate
              Rectangle {
                  ...
                  MouseArea {
                      onClicked: { /* I'd like to put something here */ }
                  }
              }
          }
          ListView {
              id: listView
              delegate: listDelegate
          }
      }
      

      I use this list like so:

      ListModel {
          id: zoneDetailModel
          ListElement { parameter: "text1"; value: "value1"}
          ListElement { parameter: "text2"; value: "value2"}
          ListElement { parameter: "text3"; value: "value3"}
      }
      
      Roundlist {
          model: zoneNameModel
      }
      

      Is there a way to designate an action for the onClicked() in my model? If not, is there another way to accomplish this?

      Thanks...

      fcarneyF Offline
      fcarneyF Offline
      fcarney
      wrote on last edited by
      #12

      @mzimmers

      // Roundlist.qml
      Rectangle { // list background
          property alias model: listView.model
      
          signal doClick(ind index)
      
          Component {
              id: listDelegate
              Rectangle {
                  ...
                  MouseArea {
                      onClicked: { doClick(index) }
                  }
              }
          }
          ListView {
              id: listView
              delegate: listDelegate
          }
      }
      

      Then use:

      ListModel {
          id: zoneDetailModel
          ListElement { parameter: "text1"; value: "value1"; funcIndex: 0}
          ListElement { parameter: "text2"; value: "value2"; funcIndex: 1}
          ListElement { parameter: "text3"; value: "value3"; funcIndex: 2}
      }
      
      property var funcs: [
        function(){ //do stuff},
        function(){ //do stuff},
        function(){ //do stuff},
      ]
      
      Roundlist {
          model: zoneNameModel
      
         onDoClick: {
            funcs[index]()
         }
      }
      

      You could also pass a parameter if you really want via the signal.
      You cannot put a function like this in your model. That won't work with ListModel. You have to have a separate structure to point to the function. You could define your functions outside the list as well and reference by name.

      C++ is a perfectly valid school of magic.

      mzimmersM 2 Replies Last reply
      1
      • fcarneyF fcarney

        @mzimmers

        // Roundlist.qml
        Rectangle { // list background
            property alias model: listView.model
        
            signal doClick(ind index)
        
            Component {
                id: listDelegate
                Rectangle {
                    ...
                    MouseArea {
                        onClicked: { doClick(index) }
                    }
                }
            }
            ListView {
                id: listView
                delegate: listDelegate
            }
        }
        

        Then use:

        ListModel {
            id: zoneDetailModel
            ListElement { parameter: "text1"; value: "value1"; funcIndex: 0}
            ListElement { parameter: "text2"; value: "value2"; funcIndex: 1}
            ListElement { parameter: "text3"; value: "value3"; funcIndex: 2}
        }
        
        property var funcs: [
          function(){ //do stuff},
          function(){ //do stuff},
          function(){ //do stuff},
        ]
        
        Roundlist {
            model: zoneNameModel
        
           onDoClick: {
              funcs[index]()
           }
        }
        

        You could also pass a parameter if you really want via the signal.
        You cannot put a function like this in your model. That won't work with ListModel. You have to have a separate structure to point to the function. You could define your functions outside the list as well and reference by name.

        mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by
        #13

        @fcarney very understandable; thanks. A couple questions:

        1. instead ofthe explicit funcIndex values, can the call to doClick() somehow extract the index of the zoneDetailModel? That would make the implementation just a bit cleaner.
        2. If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?

        Thanks...this is really helpful.

        fcarneyF 2 Replies Last reply
        0
        • mzimmersM mzimmers

          @fcarney very understandable; thanks. A couple questions:

          1. instead ofthe explicit funcIndex values, can the call to doClick() somehow extract the index of the zoneDetailModel? That would make the implementation just a bit cleaner.
          2. If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?

          Thanks...this is really helpful.

          fcarneyF Offline
          fcarneyF Offline
          fcarney
          wrote on last edited by
          #14

          @mzimmers Yeah, I started that thought, but didn't finish. Should be able to use the funcIndex from the model instead of the model index that is implied.

          So you could call doClick(funcIndex) instead.

          C++ is a perfectly valid school of magic.

          1 Reply Last reply
          0
          • mzimmersM mzimmers

            @fcarney very understandable; thanks. A couple questions:

            1. instead ofthe explicit funcIndex values, can the call to doClick() somehow extract the index of the zoneDetailModel? That would make the implementation just a bit cleaner.
            2. If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?

            Thanks...this is really helpful.

            fcarneyF Offline
            fcarneyF Offline
            fcarney
            wrote on last edited by
            #15

            @mzimmers said in Can an onClicked() be a property?:

            If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?

            I would use a state for that. There are all kinds of state things that can call functions and set properties on things. That is how we do dialog boxes is with states.

            C++ is a perfectly valid school of magic.

            GrecKoG 1 Reply Last reply
            1
            • fcarneyF fcarney

              @mzimmers said in Can an onClicked() be a property?:

              If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?

              I would use a state for that. There are all kinds of state things that can call functions and set properties on things. That is how we do dialog boxes is with states.

              GrecKoG Online
              GrecKoG Online
              GrecKo
              Qt Champions 2018
              wrote on last edited by
              #16

              If the list is static it doesn't need to be a ListModel, you could then have a function directly in the model:

              ListView {
                  model: [
                      { parameter: "text1", value: "value1", action: ()  => { doStuf(1) }},
                      { parameter: "text2", value: "value2", action: ()  => { doStuf(2) }},
                      { parameter: "text3", value: "value3", action: ()  => { doStuf(3) }}
                  ]
                  delegate: Item {
                      // ...
                      TapHandler {
                          onTapped: modelData.action()
                      }
                  }
              
              }
              
              mzimmersM 1 Reply Last reply
              2
              • GrecKoG GrecKo

                If the list is static it doesn't need to be a ListModel, you could then have a function directly in the model:

                ListView {
                    model: [
                        { parameter: "text1", value: "value1", action: ()  => { doStuf(1) }},
                        { parameter: "text2", value: "value2", action: ()  => { doStuf(2) }},
                        { parameter: "text3", value: "value3", action: ()  => { doStuf(3) }}
                    ]
                    delegate: Item {
                        // ...
                        TapHandler {
                            onTapped: modelData.action()
                        }
                    }
                
                }
                
                mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on last edited by
                #17

                @GrecKo @fcarney thanks for the suggestions. As I mentioned above, eventually this model will be defined in C++, so I'm not sure whether QML will view it as static, but at least i can use @fcarney's suggestion.

                1 Reply Last reply
                0
                • mzimmersM mzimmers has marked this topic as solved on
                • mzimmersM mzimmers has marked this topic as unsolved on
                • fcarneyF fcarney

                  @mzimmers

                  // Roundlist.qml
                  Rectangle { // list background
                      property alias model: listView.model
                  
                      signal doClick(ind index)
                  
                      Component {
                          id: listDelegate
                          Rectangle {
                              ...
                              MouseArea {
                                  onClicked: { doClick(index) }
                              }
                          }
                      }
                      ListView {
                          id: listView
                          delegate: listDelegate
                      }
                  }
                  

                  Then use:

                  ListModel {
                      id: zoneDetailModel
                      ListElement { parameter: "text1"; value: "value1"; funcIndex: 0}
                      ListElement { parameter: "text2"; value: "value2"; funcIndex: 1}
                      ListElement { parameter: "text3"; value: "value3"; funcIndex: 2}
                  }
                  
                  property var funcs: [
                    function(){ //do stuff},
                    function(){ //do stuff},
                    function(){ //do stuff},
                  ]
                  
                  Roundlist {
                      model: zoneNameModel
                  
                     onDoClick: {
                        funcs[index]()
                     }
                  }
                  

                  You could also pass a parameter if you really want via the signal.
                  You cannot put a function like this in your model. That won't work with ListModel. You have to have a separate structure to point to the function. You could define your functions outside the list as well and reference by name.

                  mzimmersM Offline
                  mzimmersM Offline
                  mzimmers
                  wrote on last edited by
                  #18

                  @fcarney I implemented your suggestion like so:

                  ListModel {
                      id: zoneDetailModel
                      ListElement { parameter: "param0"; value: "value0"; funcIndex: 0 }
                      ListElement { parameter: "param1"; value: "value1"; funcIndex: 1  }
                      ListElement { parameter: "param2"; value: "value2"; funcIndex: 2  }
                  }
                  
                  property var funcs: [
                      function() { console.log("0!") },
                      function() { console.log("1!") },
                      function() { console.log("2!") },
                  ]
                  Roundlist {
                      id: detailList
                      width: newZone.width - (scroller.width * 2)
                      model: zoneDetailModel
                      onDoClick: {
                          funcs[index]()
                      }
                  }
                  

                  It seems to work, though the first time I click on one of the items, I get this:

                  qt.qml.context: qrc:/nga_demo/Newzone.qml:68:13 Parameter "index" is not declared. Injection of parameters into signal handlers is deprecated. Use JavaScript functions with formal parameters instead.
                  

                  Is this something that can be dealt with?

                  BTW: I believe that this line:

                  signal doClick(ind index)
                  

                  should be:

                  signal doClick(int index)
                  

                  yes?

                  Thanks...

                  fcarneyF 1 Reply Last reply
                  0
                  • mzimmersM mzimmers

                    @fcarney I implemented your suggestion like so:

                    ListModel {
                        id: zoneDetailModel
                        ListElement { parameter: "param0"; value: "value0"; funcIndex: 0 }
                        ListElement { parameter: "param1"; value: "value1"; funcIndex: 1  }
                        ListElement { parameter: "param2"; value: "value2"; funcIndex: 2  }
                    }
                    
                    property var funcs: [
                        function() { console.log("0!") },
                        function() { console.log("1!") },
                        function() { console.log("2!") },
                    ]
                    Roundlist {
                        id: detailList
                        width: newZone.width - (scroller.width * 2)
                        model: zoneDetailModel
                        onDoClick: {
                            funcs[index]()
                        }
                    }
                    

                    It seems to work, though the first time I click on one of the items, I get this:

                    qt.qml.context: qrc:/nga_demo/Newzone.qml:68:13 Parameter "index" is not declared. Injection of parameters into signal handlers is deprecated. Use JavaScript functions with formal parameters instead.
                    

                    Is this something that can be dealt with?

                    BTW: I believe that this line:

                    signal doClick(ind index)
                    

                    should be:

                    signal doClick(int index)
                    

                    yes?

                    Thanks...

                    fcarneyF Offline
                    fcarneyF Offline
                    fcarney
                    wrote on last edited by
                    #19

                    @mzimmers said in Can an onClicked() be a property?:

                    Injection of parameters into signal handlers is deprecated.

                    That is Qt 6 issue:
                    https://forum.qt.io/topic/139189/keystrokes-parameter-event-is-not-declared-injection-of-parameters-into-signal-handlers-is-deprecated-use-javascript-functions-with-formal-parameters-instead

                    I searched on "Injection of parameters into signal handlers is deprecated."

                    C++ is a perfectly valid school of magic.

                    mzimmersM 1 Reply Last reply
                    1
                    • fcarneyF fcarney

                      @mzimmers said in Can an onClicked() be a property?:

                      Injection of parameters into signal handlers is deprecated.

                      That is Qt 6 issue:
                      https://forum.qt.io/topic/139189/keystrokes-parameter-event-is-not-declared-injection-of-parameters-into-signal-handlers-is-deprecated-use-javascript-functions-with-formal-parameters-instead

                      I searched on "Injection of parameters into signal handlers is deprecated."

                      mzimmersM Offline
                      mzimmersM Offline
                      mzimmers
                      wrote on last edited by
                      #20

                      @fcarney ah yes, my old friend the lambda.

                      Roundlist {
                          id: detailList
                          width: newZone.width - (scroller.width * 2)
                          model: zoneDetailModel
                          onDoClick: (index)=> {
                                         funcs[index]()
                                     }
                      }
                      

                      This eliminated the error, and works fine.

                      Lambdas still look weird to me, though...

                      Thanks for the help.

                      1 Reply Last reply
                      1
                      • mzimmersM mzimmers has marked this topic as solved on

                      • Login

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