Home > OS >  How to handle press state from inside the button if contentItem is defined from the outside?
How to handle press state from inside the button if contentItem is defined from the outside?

Time:12-10

I have a custom button that shows a white overlay over the content and background area when pressed. The user of the button can specify how to align the content (label text) by defining the contentItem.

The current implementation works, but I would like to control the press state inside the button. How can the button display the white overlay on top of the contentItem from within the button?

I prefer not to add a bunch of properties to the button to define the layout of the text/icon. Is there another way to accomplish this?

Working code so far:

 ButtonOverlay {
    id: btnOverlay
    width: 100
    height: 50
    state: ""
    contentItem: Rectangle {
        color: "red"
        Label {
            text: "button"
        }
        Rectangle {
            id: rectId
            anchors.fill: parent
            color: "white"
            opacity: 0.5
            visible: btnOverlay.state === "pressed"
        }
    }
    onPressed: {
          btnOverlay.state = "pressed"
    }
    onReleased: {
          btnOverlay.state = ""
    }
}

ButtonOverlay.qml

Button {
   id: root

   background: Rectangle {
      radius: 10
      color: "gray"

      Rectangle {
        id: overlay
        anchors.fill: parent
        radius: parent.radius
        visible: root.state === "pressed"
        color: "white"
        opacity: 0.5
     }
   }
}

CodePudding user response:

Perhaps you could use Frame for your ButtonOverlay. Frame works by automatically sizing to your inner contents but allows you to easily replace the borders via the background property. To use it, you will have to move the entire Button out:

import QtQuick
import QtQuick.Controls
Page {
    ButtonOverlay {
        id: btnOverlay
        pressed: btn.pressed
        Button {
            id: btn
            width: 100
            height: 50
            implicitWidth: width
            implicitHeight: height
            contentItem: Rectangle {
                color: "red"
                Label {
                    text: "button"
                }
                Rectangle {
                    id: rectId
                    anchors.fill: parent
                    color: "white"
                    opacity: 0.5
                    visible: btnOverlay.pressed
                }
            }
        }
    }
}

// ButtonOverlay.qml

import QtQuick
import QtQuick.Controls

Frame {
    id: root
    
    property bool pressed: false
    
    background: Rectangle {
        radius: 10
        color: "gray"
        
        Rectangle {
            id: overlay
            anchors.fill: parent
            radius: parent.radius
            visible: pressed
            color: "white"
            opacity: 0.5
        }
    }
}

You can Try it Online!

CodePudding user response:

I've removed the overlay in the contentItem and moved the overlay from the background into the Button. Furthermore I've used the z property to change the drawing order.

component ButtonOverlay: Button {
    id: btn

    background: Rectangle {
        radius: 10
        color: "gray"
    }

    Rectangle {
        id: overlay
        anchors.fill: parent
        radius: btn.background.radius
        color: "white"
        opacity: 0.5
        visible: btn.pressed
        z: 1
    }
}

ButtonOverlay {
    width: 100
    height: 50
    contentItem: Rectangle {
        color: "red"

        Label { text: "button" }
    }
}
  • Related