When developing Buttons, you often want to have images as backgrounds. One image for the pressed state and one for the released state. I would like to show several possibilities, which get’s more elegant towards the end.
As usual these are not really functional buttons it’s merely to present the ui.
Everything code snippet presented is inside this Rectangle code:
Rectangle { width: 200; height: 260 color: "gray" // code goes here MouseRegion { id: region; anchors.fill: parent; } }
For simplicity I only use one mouse region, which covers the whole root-rectangle.
Here is a screen-shot of the final results of all 4 tries for your reference.
And here the two button backgrounds I use.
Pressed Background
As you might have guessed by now, I’m not a designer 😉
I designed the button backgrounds to have a size of 96px x 48px. The pressed button is the released button with 50% opacity. I used a double linear blend for the color gradient.
First Try
My first try is using 2 images, one for the pressed and one for the released state. I change the images by switching their opacity (0-invisible … 1-visible) based on the mouse region pressed property.
// [1] fixed size button with image background Item { x: 10; y: 20; width: 96; height: 48 Image { source: "images/button_released.png"; opacity: region.pressed? 0: 1 } Image { source: "images/button_pressed.png"; opacity: region.pressed? 1: 0 } }
Instead of opacity, it’s also possible to use the visible
property for switching the visible state.
Second Try
Now I would like to make the button to adapt to a larger size, so I changed the width of the button.
// [2] dynamic size button with image background Item { x: 10; y: 80; width: parent.width-20; height: 48; Image { anchors.fill: parent; source: "images/button_released.png"; opacity: region.pressed? 0: 1 } Image { anchors.fill: parent; source: "images/button_pressed.png"; opacity: region.pressed? 1: 0 } }
Have a close look on the 2nd button from the image above. You can see that the border is stretched and does not look really nice. This is due to the fact that the background image get’s stretched when the button is stretched.
Third-Try
To overcome the stretching issue, QML has the BorderImage element. It allows to specify a source image and the borders to be used from the image. This is similar to CSS. This information can be stored in a .sci file like this:
border.left: 10 border.top: 12 border.bottom: 12 border.right: 10 source: button_pressed.png
The source attribute is relative to the location where the .sci file resides
So with the BorderImage in use our source code looks like this now.
// [3] dynamic size button with border-image background Item { x: 10; y: 140; width: parent.width-20; height: 48; BorderImage { anchors.fill: parent; source: "images/button_released.sci"; opacity: region.pressed? 0: 1 } BorderImage { anchors.fill: parent; source: "images/button_pressed.sci"; opacity: region.pressed? 1: 0 } }
Fourth-Try
I created earlier the pressed-button image by decreasing the opacity by 50%. In this try I will use QML to do this effect directly on the image. So I use only one image. This allows me also to use the BorderImage itself as the button.
// [4] dynamic sized button as a border image BorderImage { x: 10; y: 200; width: parent.width-20; height: 48; source: "images/button_released.sci"; opacity: region.pressed? .5: 1 }
This is already something more useful. I hope you liked my approach. Please provide feedback so I can enhance these posts. Thanks.