Qt World Summit: Register Today!

Qml progress bar with slanting progression

  • I am trying to implement a progress bar with the below images
    I am using a method like placing the progress image over the backimage and increasing the width of progress image

    Image {
    source: "background.png"

        Rectangle {
            id: idRectangleLow
            Image {
                source: "progress.png"
            width: factor           

    but this method fails at the slanting strips.These strips are specific points in progression.Is there any scope to
    increase the width with a slanting or should I use another approach to achieve this.If you have any idea please comment.

  • Here is what I can suggest as a solution :

    Create a QML that create a progress bar using ColorOverlay.

    Bar.qml :

    import QtQuick 2.0
    import QtGraphicalEffects 1.0
        id: imgContainer
        property string source
        property color fillColor
        property int value: value
        Image {
            id: backgroundImage
            source: imgContainer.source
            anchors.fill: parent
            smooth: true
            visible: false
        ColorOverlay {
            id: overlay
            visible: backgroundImage.status == Image.Ready
            anchors.fill: backgroundImage
            source: backgroundImage
            color: fillColor
            visible: coloredImage.status == Image.Ready && overlay.visible
            id: coloredImage
            anchors.fill: parent
            source: imgContainer.source
            smooth: true
            layer.enabled: true
            layer.effect: OpacityMask {
                maskSource: Item {
                    width: coloredImage.width
                    height: coloredImage.height
                        id: clipRect
                        anchors.bottom: parent.bottom
                        anchors.left: parent.left
                        anchors.top: parent.top
                        width:  (coloredImage.width/100)*value
                        clip: true
                        color: "transparent"
                        Rectangle {
                            id: maskRect
                            anchors.bottom: parent.bottom
                            width:  imgContainer.width
                            height: imgContainer.height

    Then use it with your colored image in your main

    main.qml :

    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.4
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        Slider {
            id : slider
            width: parent.width
            minimumValue: 0
            maximumValue : 100
            width: 400
            height: 50
            anchors.centerIn: parent
            source: "progress.png"
            fillColor: "#505254"
            value: slider.value
            anchors.top: slider.bottom

    Here is the result it gives me :

    It is a bit less clean in terms of result I think but it works

  • @DavidM29 Thank you for your time and effort.I run your code but as I asked in question is there any scope to preserve the
    slanting stripes.As we increase the width of 'clipRect' rectangle at border of the stripe it should completly overlap
    the stripe with a slanting.Otherwise a slanting increase in width of rectangle.

  • Oh ok sorry I misunderstood your problem.
    What you want here is that it progress with the same angle as the slopped lines you have on your image instead of the straigth line I gave you.

    Do you have your image in a svg file ? If you can provide it to me I can try something

  • @DavidM29 Sorry I dont currently have the svg format.All the slopped lines are in angle '73' what should I do to have a slanting progress.

  • I'm not sure it is the best solution but I started to try something.

    Here is what I'm thinking of.
    I tried to make a slopped shape at the angle of your progress lines. I mask the progress image in that shape and what I was trying to do is use this mask on top of the background.

    I'm still trying something but here is a preview of the masked progress
    it is the progress on the bottom, the one on the top is just an upgraded version of what I provided you on my first answer.

    Here is the shape I use as a mask :

  • Moderators

    hi @prasanth ,

    to do this purly with 2 images is going to be difficult.

    I would suggest the following:

    • Load your backround img in a Image-element
    • create a Canvas2d ontop of that Image-element
    • draw a path along the target area, and make the width dependent on the actual progress
    • fill that paw with the target color

    that should solve your issue, I think :)

Log in to reply