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. specifying Button:onClicked via property
Forum Updated to NodeBB v4.3 + New Features

specifying Button:onClicked via property

Scheduled Pinned Locked Moved Solved QML and Qt Quick
13 Posts 6 Posters 4.1k 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.
  • JoeCFDJ Offline
    JoeCFDJ Offline
    JoeCFD
    wrote on last edited by JoeCFD
    #2

    Can not you simply inherit a button for example:

    TabButton  {
        id: root
        background: Rectangle {
            width: root.width
            height: root.height
            color: root.checked ? StyleSheet.mainActive : StyleSheet.greyBackground
        }
    
        onClicked: {
            if ( root.checked ) {
                ----------switch pane----------
            }
        }
    }
    
    1 Reply Last reply
    0
    • mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #3

      My custom button is going to have to be fairly "open" when it comes to the onClicked() activity:

      • push something onto a stack
      • pop something off of a stack
      • send a signal of some kind back to the C++ code
      • etc.

      I really need to parameterize the action (if this is possible).

      L 1 Reply Last reply
      0
      • mzimmersM mzimmers

        My custom button is going to have to be fairly "open" when it comes to the onClicked() activity:

        • push something onto a stack
        • pop something off of a stack
        • send a signal of some kind back to the C++ code
        • etc.

        I really need to parameterize the action (if this is possible).

        L Offline
        L Offline
        lemons
        wrote on last edited by
        #4

        @mzimmers if you want to add an onClicked signal to your rectangle:

        // Pill.qml
        Rectangle {
            id: pill
            signal clicked
        
            MouseArea {
                anchors.fill: parent
                onClicked: pill.clicked()
            }
        }
        
        // main.qml
        Pill {
            width: 200
            height: 200
            color: "red"
            onClicked: {
                console.debug("pill clicked")
            }
        }
        

        if you want to pass an action as parameter to the object:

        // Pill.qml
        Rectangle {
            id: pill
            property var action: function () {}
        
            MouseArea {
                anchors.fill: parent
                onClicked: action()
            }
        }
        
        // main.qml
        Pill {
            width: 200
            height: 200
            color: "red"
            action: function () {
                console.debug("action passed to mousearea of pill")
            }
        }
        
        1 Reply Last reply
        2
        • GrecKoG Offline
          GrecKoG Offline
          GrecKo
          Qt Champions 2018
          wrote on last edited by
          #5

          Just customize a QQC2 button, don't recreate your own from scratch.

          mzimmersM 1 Reply Last reply
          0
          • GrecKoG GrecKo

            Just customize a QQC2 button, don't recreate your own from scratch.

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

            @GrecKo I don't see how that would solve my problem.

            GrecKoG 1 Reply Last reply
            0
            • mzimmersM mzimmers

              Hi all -

              I'm implementing an app that will make copious use of customized buttons (really Rectangles with MouseAreas, probably). I need to be able to specify for each of my buttons what behavior to take when clicked. Can I do this using a property? If not, does anyone have a recommendation?

              Rectangle {
                  id: pill
              
                  // stuff
                  
                  MouseArea {
                      anchors.fill: parent
                      onClicked: // what do I put here?
                  }
              }
              

              Thanks...

              B Offline
              B Offline
              Bob64
              wrote on last edited by Bob64
              #7

              @mzimmers if I understand what you want correctly, all you need to do is to expose a property in your root component (or maybe a property alias to the mouse area's onClicked property) that expects to be assigned an on-clicked handler function:

              MyButton.qml

              Rectangle {
                  id: pill
                  property var onClickedHandler
                  // stuff
                  
                  MouseArea {
                      anchors.fill: parent
                      onClicked: pill.onClickedHandler()
                  }
              }
              

              Usage:

                   function handler1() { ... }
                   function handler2() { ... }
                   ...
                   MyButton {
                      id: but1
                      onClickedHandler: handler1
                   }
                   MyButton {
                      id: but2
                      onClickedHandler: handler2
                   }
              
              mzimmersM 1 Reply Last reply
              1
              • B Bob64

                @mzimmers if I understand what you want correctly, all you need to do is to expose a property in your root component (or maybe a property alias to the mouse area's onClicked property) that expects to be assigned an on-clicked handler function:

                MyButton.qml

                Rectangle {
                    id: pill
                    property var onClickedHandler
                    // stuff
                    
                    MouseArea {
                        anchors.fill: parent
                        onClicked: pill.onClickedHandler()
                    }
                }
                

                Usage:

                     function handler1() { ... }
                     function handler2() { ... }
                     ...
                     MyButton {
                        id: but1
                        onClickedHandler: handler1
                     }
                     MyButton {
                        id: but2
                        onClickedHandler: handler2
                     }
                
                mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on last edited by
                #8

                @Bob64 @lemons thanks; this will work. I wonder -- is it possible to avoid using a function for this? No big deal if it isn't; it would just simplify the coding a bit.

                B 1 Reply Last reply
                0
                • mzimmersM mzimmers

                  @Bob64 @lemons thanks; this will work. I wonder -- is it possible to avoid using a function for this? No big deal if it isn't; it would just simplify the coding a bit.

                  B Offline
                  B Offline
                  Bob64
                  wrote on last edited by
                  #9

                  @mzimmers I think you mean just to use a "Javascript block" (not sure of technical term) like this:

                       onClickHandler: {
                          // do stuff
                       }
                  

                  and have that passed down to the onClicked property of the MouseArea?

                  I don't think that would work, though I can't explain the technicalities of it. You can almost get there with an "inline" function of some description though. If you have a later version of Qt than I have, I think you can use JS "arrow functions" like this:

                       onClickHandler: () => {
                          // do stuff
                       }
                  

                  (If the function had arguments, they would go in the () but here it's an empty arg list.)

                  The older approach to do something similar is the anonymous function:

                       onClickHandler: function() {
                          // do stuff
                       }
                  
                  mzimmersM 1 Reply Last reply
                  0
                  • B Bob64

                    @mzimmers I think you mean just to use a "Javascript block" (not sure of technical term) like this:

                         onClickHandler: {
                            // do stuff
                         }
                    

                    and have that passed down to the onClicked property of the MouseArea?

                    I don't think that would work, though I can't explain the technicalities of it. You can almost get there with an "inline" function of some description though. If you have a later version of Qt than I have, I think you can use JS "arrow functions" like this:

                         onClickHandler: () => {
                            // do stuff
                         }
                    

                    (If the function had arguments, they would go in the () but here it's an empty arg list.)

                    The older approach to do something similar is the anonymous function:

                         onClickHandler: function() {
                            // do stuff
                         }
                    
                    mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #10

                    @Bob64 good input. What I was originally thinking of was something like:

                    Rectangle {
                        id: pill
                        property var doStuff
                        // stuff
                        
                        MouseArea {
                            anchors.fill: parent
                            onClicked: doStuff
                        }
                    }
                    

                    But stepping back, I think I'm trying to do something that will create more work than it will solve.

                    1 Reply Last reply
                    0
                    • mzimmersM mzimmers

                      @GrecKo I don't see how that would solve my problem.

                      GrecKoG Offline
                      GrecKoG Offline
                      GrecKo
                      Qt Champions 2018
                      wrote on last edited by
                      #11

                      @mzimmers said in specifying Button:onClicked via property:

                      @GrecKo I don't see how that would solve my problem.

                      A Button already has a clicked signal.
                      If you only want to customize the look of your button, inherit from a base Button and change the contentItem and/or the background property of it.

                      \\ MyCustomButton.qml
                       import QtQuick.Controls
                      Button {
                          id: control
                          background: // ...
                          contentItem: // ...
                      }
                      

                      Then you don't have to do anything special for the click and just use it like so:

                      MyCustomButton {
                         onClicked: doSomething();
                      }
                      

                      You don't need more than that. This onClickedHandler is superfluous.
                      And you still have access to the Qt Quick Controls features like font and style inheriting, padding, inset, clickPolicy, etc..

                      mzimmersM 1 Reply Last reply
                      0
                      • GrecKoG GrecKo

                        @mzimmers said in specifying Button:onClicked via property:

                        @GrecKo I don't see how that would solve my problem.

                        A Button already has a clicked signal.
                        If you only want to customize the look of your button, inherit from a base Button and change the contentItem and/or the background property of it.

                        \\ MyCustomButton.qml
                         import QtQuick.Controls
                        Button {
                            id: control
                            background: // ...
                            contentItem: // ...
                        }
                        

                        Then you don't have to do anything special for the click and just use it like so:

                        MyCustomButton {
                           onClicked: doSomething();
                        }
                        

                        You don't need more than that. This onClickedHandler is superfluous.
                        And you still have access to the Qt Quick Controls features like font and style inheriting, padding, inset, clickPolicy, etc..

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

                        @GrecKo OK, now I see what you're saying, and I agree that would make things a little easier. I'm wondering how much I can customize the button: can I have multiple lines of text? And, if necessary, use multiple fonts/sizes for the text?

                        Thanks...

                        1 Reply Last reply
                        0
                        • johngodJ Offline
                          johngodJ Offline
                          johngod
                          wrote on last edited by
                          #13

                          I know this is marked as solved but just wanted to add my 2 cents.
                          I did this by adding a property int type and a signal with a argument in my button, then calling the mouse click handler would invoke the signal with the type argument. Then outside on your menu were you have all your buttons, each button click will call another menu signal that receives the button type. Then you just add a bunch of if else's or a switch case to handle every type of button. Something like this:
                          Pill.qml:

                          Rectangle {
                              id: pill
                              property int type
                              signal btnClick(btnSignal: int)
                              
                              MouseArea {
                                  anchors.fill: parent
                                  onClicked: btnClick(type)
                              }
                          }
                          

                          Then on your menu:

                          signal handlePills(type: int) 
                          
                          onHandlePills: function(type){
                              if (type === stuff1)
                                  doStuff1()
                          
                              if (type === stuff2)
                                  doStuff2()
                          .......
                          }
                          
                          
                          Pill {
                              type: stuff1
                              onBtnClick: handlePills(type)
                          }
                          
                          Pill {
                              type: stuff2
                              onBtnClick: handlePills(type)
                          }
                          

                          To make this more elegant you can create a qml enum and use it on type. I dont know your use case but to me was less error prone and more elegant code.

                          Taking another step further, and since I needed a dynamic menu where I could add or remove buttons, I created a listview, a model and button delegate, to create the menu with buttons. Then only took me a line of code to add a button:

                          function showMenuCommands() {
                                  menuCommands.modelMenu.clear()
                                  menuCommands.modelMenu.append({"textName": "copy", "typeName": Commands.Copy})
                                  menuCommands.modelMenu.append({"textName": "move", "typeName": Commands.Move})
                                  menuCommands.modelMenu.append({"textName": "scale", "typeName": Commands.Scale})
                                  ........
                              }
                          
                          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