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.0k 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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #1

    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 1 Reply Last reply
    0
    • 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