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. Rounded button with progress background fill
QtWS25 Last Chance

Rounded button with progress background fill

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qmlbuttonprogressmaskclipping
3 Posts 2 Posters 2.0k Views
  • 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.
  • M Offline
    M Offline
    markugra
    wrote on 23 Jan 2018, 00:10 last edited by
    #1

    Hi,

    I would like to create a count-down button with rounded corners and a background that fills/empties proportionally to the elapsed time. Something like this:0_1516664109975_CountDownButton.png

    I thought I could do this using two rectangles as the button background where the black one has a width proportional to the time and the corners on the left would be clipped by the other Rectangle. Something like this:

    Button{
    	id: control
    	...
    	background: Rectangle {
    		id: backgroundRect
    		implicitWidth: 100
    		implicitHeight: 60
    		radius: height / 2
    		anchors.fill: parent
    		color: "gray"
    
    		Rectangle{
    			id: progressRect
    			anchors.verticalCenter: backgroundRect.verticalCenter
    			anchors.left: backgroundRect.left
    			clip: true
    			height: backgroundRect.height
    			width: relativeCounter*backgroundRect.width
    			color: "black"
    		}
    	}
    }
    

    However the clipping works only along the bounding box, i.e. the corners on the left are not rounded:
    0_1516665332755_CountDownButton_wrong.png

    I tried OpacityMask in the GraphicalEffects module, but I think I cannot use the parent rectangle as mask. I tried to work around it but could not get it to run. The last option I see is using Canvas and describing the round corners mathematically.

    I am new to QML so it is quite possible that I did something wrong in the steps I tried or that I am missing a simpler option.

    If anyone has an idea how it should work or can confirm that something does not work, I am grateful for any help.

    Thanks in advance

    R 1 Reply Last reply 23 Jan 2018, 07:40
    0
    • M markugra
      23 Jan 2018, 00:10

      Hi,

      I would like to create a count-down button with rounded corners and a background that fills/empties proportionally to the elapsed time. Something like this:0_1516664109975_CountDownButton.png

      I thought I could do this using two rectangles as the button background where the black one has a width proportional to the time and the corners on the left would be clipped by the other Rectangle. Something like this:

      Button{
      	id: control
      	...
      	background: Rectangle {
      		id: backgroundRect
      		implicitWidth: 100
      		implicitHeight: 60
      		radius: height / 2
      		anchors.fill: parent
      		color: "gray"
      
      		Rectangle{
      			id: progressRect
      			anchors.verticalCenter: backgroundRect.verticalCenter
      			anchors.left: backgroundRect.left
      			clip: true
      			height: backgroundRect.height
      			width: relativeCounter*backgroundRect.width
      			color: "black"
      		}
      	}
      }
      

      However the clipping works only along the bounding box, i.e. the corners on the left are not rounded:
      0_1516665332755_CountDownButton_wrong.png

      I tried OpacityMask in the GraphicalEffects module, but I think I cannot use the parent rectangle as mask. I tried to work around it but could not get it to run. The last option I see is using Canvas and describing the round corners mathematically.

      I am new to QML so it is quite possible that I did something wrong in the steps I tried or that I am missing a simpler option.

      If anyone has an idea how it should work or can confirm that something does not work, I am grateful for any help.

      Thanks in advance

      R Offline
      R Offline
      raven-worx
      Moderators
      wrote on 23 Jan 2018, 07:40 last edited by raven-worx
      #2

      @markugra said in Rounded button with progress background fill:

      I tried OpacityMask in the GraphicalEffects module, but I think I cannot use the parent rectangle as mask.

      exactly, you need to place the button and the rectangle "beside the button on the same level"
      You could group the button and the rectangle into a custom component then.
      See the example in the docs and replace it analogous with your button and rectangle elements.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      2
      • M Offline
        M Offline
        markugra
        wrote on 23 Jan 2018, 18:04 last edited by
        #3

        Thanks, I tried the OpacityMask again as you suggested and it works now. It took me a bit to get it right, because i) I had a warning about the recursive property in ShaderEffectSource needing to be set to "true" and ii) the mask size needs to be the same as the source size for it to work properly. After a while I noticed that i) originated from some code in the contentItem of the button using the ColorOverlay (in fact it was the same problem there i.e. I tried to apply it to the parent). To fix ii) I used a transparent frame so that the code now looks something like:

        background:
                Item{
                    width: control.width
                    height: control.height
                    Rectangle{
                        id: progressFrame
                        anchors.fill: parent
                        color: "transparent"
                        visible: false
                        Rectangle{
                            id: progressRect
                            width: 0.7*parent.width
                            height: parent.height
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.left: parent.left
                            color: "green"
                        }
                    }
                    Rectangle {
                        id: backgroundRect
                        anchors.fill: parent
                        radius: height / 2
                        color: "red"
                        visible: true
                    }
        
                    OpacityMask{
                    anchors.fill: progressFrame
                    source: progressFrame
                    maskSource: backgroundRect
                    }
                }
        

        Resulting in:
        0_1516730617237_960aab10-96cd-4f9e-b86d-afd96504a439-image.png

        Thanks again!

        1 Reply Last reply
        0

        1/3

        23 Jan 2018, 00:10

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved