QML RadialBar component

Radial Bar is a highly customizable QML component created using QQuickPaintedItem class.
This is a useful component to be used for any QML application to show the status of progress.

Following are the list of main properties supported by this component.

  • startAngle
  • spanAngle
  • minValue
  • maxValue
  • value
  • dialWidth
  • backgroundColor
  • foregroundColor
  • progressColor
  • textColor
  • penStyle
  • suffixText
  • showText
  • dialType
  • textFont

The property penStyle can be used to provide two styles which Qt is providing which are Qt::FlatCap & Qt::RoundCap.

The property DialType is provided as custom enum which will have following properties.

  • FullDial
  • MinToMax
  • NoDial

Below is the sample usage of RadialBar component.

RadialBar {
     width: 300
     height: 300
     penStyle: Qt.RoundCap
     dialType: RadialBar.FullDial
     progressColor: "#1dc58f"
     foregroundColor: "#191a2f"
     dialWidth: 30
     startAngle: 180
     spanAngle: 70
     minValue: 0
     maxValue: 100
     value: 50
     textFont {
         family: "Halvetica"
         italic: false
         pointSize: 16
     }
     suffixText: "%"
     textColor: "#FFFFFF"
}

Screenshots:

04_Radial_Dial

Source code:

https://github.com/arunpkqt/RadialBarDemo

New version of RadialBar rewritten using Qt Quick Shape is now available here,

https://github.com/arunpkqt/RadialBarDemo/blob/master/RadialBarShape.qml

This can be used a s a drop-in replacement for the previous RadialBar component.

Related latest blog post is available here

QML RadialBarShape

Update:

A port of QML RadialBar using PyQt is available at,

http://pyjuice.com/porting-radialbar-cqt-pyqt/

19 responses to “QML RadialBar component”

  1. How use it to have one RadialBar on my QML page?…

    Like

    1. Hi Philippe, You can see the code and sample QMl file at https://github.com/arunpkqt/RadialBarDemo.
      Only thing you need is the radialbar.h/.cpp file and register it in main.cpp and create component in QML.

      Like

  2. Nice work! I have a little problem tough: I’m changing the bar value with a timer as follows:
    Timer {
    id: testRefreshTimer
    interval: 2000
    running: true
    repeat: true
    onTriggered: {
    testRadialBar.value = 20
    }
    }
    I assumed that setting the value would trigger an update on the element but the bar gets not updated. What am I missing?

    Like

    1. Thanks Adrian. and sorry for the delay. I was quite busy with my work. if I remember correctly I have tried with attaching a slider to the Dial and change the value. I will check once I get some time. Feel free to investigate and also If you find any issue or improvement then add a patch..Happy coding!

      Like

    2. Hi Adrian, I have found the issue that update() call was missing on the setValue() method. Now I have corrected and committed the changes to Git.

      Like

  3. Hi Arun, Very nice example on RadialBar.
    I’m a newbie to QML.
    Can you please tell how to update the RadialBar value dynamically.

    Like

    1. Hello Karthik welcome to the world of Qt and QML. You just need to create a Slider item in QML and attach its value to the Value of RadialBar.

      Slider{
      id: mySlider
      }

      RadialBar{
      value: mySlider.value
      }

      I would recommend you to go through the basics of QML property change.

      Like

  4. Hi Arun Pk.

    Thank you for publishing this nice progress control. It works fine in my project and visualizes a timer.

    Best regards,
    bkweb

    Like

  5. Hi Arun,

    I am new to qml. i am trying to call the setValue(100) method at the constructor of radialbar(). But the qml file value is always loaded. How to setValue at the time of start of radial bar? based on userinput either 100 or 200?

    Regards,
    Bala

    Like

    1. Hi bala.
      You can use in QML
      RadialBar {
      id: mybar
      Component.onCompleted: mybar.value = 100
      }

      Like

  6. Hi,
    I am new to QML. I went through your source for the radial bar chart and it was very helpful. But, I wanted to display this chart as a nested one. Any suggestions on how it can be achieved.

    I want something like this:

    Thanks in advance.

    Like

  7. Hi Lakshmanan, Glad that you found it helpful.

    You can use a Repeater with RadialBar as its delegate and adjust the size accordingly. here is the sample

    Repeater {
    id: parentRepeater
    model: 5

    property var values: [37, 35, 17, 6, 3]

    delegate: RadialBar {
    width: 400 – index * 60
    height: width
    anchors.centerIn: parent
    minValue: 0
    maxValue: 40
    value: parentRepeater.values[index]
    startAngle: 180
    dialWidth: 20
    progressColor: “#65ab98”
    foregroundColor: “transparent”
    penStyle: Qt.RoundCap
    textColor: “transparent”
    }
    }

    Like

  8. Hello everyone. How to turn it into a clickable clock with its pointer snapping onto 1h interval? Thanks.

    Like

    1. hey ATON,

      What do you mean by a clickable clock?

      Here is a quick example of how it can be used to display as a clock.

      Window {
      id: root
      visible: true
      width: 1024
      height: 600
      title: qsTr(“Clock”)

      property int hours
      property int minutes
      property int seconds

      function timeChanged() {
      var date = new Date;
      hours = date.getHours()
      minutes = date.getMinutes()
      seconds = date.getUTCSeconds();
      }

      Timer {
      interval: 100; running: true; repeat: true;
      onTriggered: root.timeChanged()
      }

      property int value: 0

      Label {
      anchors.centerIn: parent
      color: “black”
      font.pointSize: 14
      text: Number(hours) + “:” + Number(minutes) + “:” + Number(seconds)
      }

      RadialBar {
      anchors.centerIn: parent
      width: 340
      height: width

      startAngle: 180
      spanAngle: 360
      dialWidth: 20
      minValue: 0
      maxValue: 60
      progressColor: “#73a011”
      foregroundColor: “transparent”
      penStyle: Qt.RoundCap
      value: root.hours
      textColor: “transparent”
      }

      RadialBar {
      anchors.centerIn: parent
      width: 340
      height: width

      startAngle: 180
      spanAngle: 360
      dialWidth: 20
      minValue: 0
      maxValue: 60
      progressColor: “#a09877”
      foregroundColor: “transparent”
      penStyle: Qt.RoundCap
      value: root.minutes
      textColor: “transparent”
      }

      RadialBar {
      anchors.centerIn: parent
      width: 400
      height: width

      startAngle: 180
      spanAngle: 360
      dialWidth: 20
      minValue: 0
      maxValue: 60
      progressColor: “#65ab98”
      foregroundColor: “transparent”
      penStyle: Qt.RoundCap
      value: root.seconds
      textColor: “transparent”
      }
      }

      Liked by 1 person

  9. Thanks for replying, Arun.
    I’m trying to implement a simple analog time picker (with hours only) with a pointer snapping within an interval of 1h and showing the time picked on the centre of circle like the example below.

    Like

    1. Hey obrasillafora,

      I don’t think that this RadialBar component is the right for your use case because you need to interact with it to pick the time.

      I would suggest having a look at this component from Ekke looks similar to the Android time picker.
      You might need to modify it in the way you want.
      https://github.com/ekke/c2gQtCon_x/blob/master/qml/popups/TimePicker.qml

      Liked by 1 person

  10. Hi Arun,

    sorry, I wasn’t clear. My question: is it possible to turn this radialbar into a 360 dial? I’ve been looking reference for so long.

    Like

  11. Hi obrasillafora,

    I was working on it for the last week and finally made it ready. here you find my blog about it

    QML Circular Slider

    Liked by 1 person

Leave a comment