specifying Button:onClicked via property
-
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...
-
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---------- } } }
-
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).
-
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).
@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") } }
-
Just customize a QQC2 button, don't recreate your own from scratch.
-
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...
@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 }
-
@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 }
-
@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 theMouseArea
?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 }
-
@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 theMouseArea
?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 }
@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.
-
@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 thecontentItem
and/or thebackground
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.. -
@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 thecontentItem
and/or thebackground
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.. -
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}) ........ }