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. QML Circular Gauge Styling - Needle trailing colour/glow
Forum Updated to NodeBB v4.3 + New Features

QML Circular Gauge Styling - Needle trailing colour/glow

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
11 Posts 5 Posters 10.8k Views 1 Watching
  • 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.
  • J Offline
    J Offline
    jars121
    wrote on last edited by jars121
    #1

    G'day,

    I'm playing with circular gauge styling in QML and am wondering how I could implement a glowing colour trailing the needle like in this gauge:

    0_1522221562391_Screen Shot 2018-03-28 at 6.17.44 pm.png

    In essence, the colour starts off with a high opacity, which gradually diminishes with distance away from the needle.

    Thanks!

    1 Reply Last reply
    0
    • timdayT Offline
      timdayT Offline
      timday
      wrote on last edited by timday
      #2

      ShaderEffect is made for this sort of bling

      I got this:

      QML gauge

      from this:

      import QtQuick 2.2
      
      Rectangle {
        id: main
        width: 512
        height: 512
        color: 'black'
      
        // Put some text in the background just to check opacity
        Text {
          x: main.width/6.0-0.5*contentWidth
          y: main.height/2.0-0.5*contentHeight
          text: '30'
          color: 'white'
        }
        Text {
          x: main.width/2.0-0.5*contentWidth
          y: main.height/6.0-0.5*contentHeight
          text: '60'
          color: 'white'
        }
        Text {
          x: 5.0*main.width/6.0-0.5*contentWidth
          y: main.height/2.0-0.5*contentHeight
          text: '90'
          color: 'white'
        }
      
        // Shader effect to provide gradient-based gauge
        ShaderEffect {
          id: gauge
          anchors.fill: parent
      
          opacity: 0.75  // Making it totally opaque on leading edge obscures the number!
      
          // Angles measured clockwise from up, in range -pi to pi
          property real angleBase: -pi*0.75
          property real angle
      
          readonly property real pi: 3.1415926535897932384626433832795
      
          vertexShader: "
            uniform highp mat4 qt_Matrix;
            attribute highp vec4 qt_Vertex;
            attribute highp vec2 qt_MultiTexCoord0;
            varying highp vec2 coord;
            void main() {
              coord = qt_MultiTexCoord0;
              gl_Position = qt_Matrix * qt_Vertex;
            }"
      
          fragmentShader: "
            uniform lowp float qt_Opacity;
            uniform highp float angleBase;
            uniform highp float angle;
            varying highp vec2 coord;
            void main() {
              gl_FragColor = vec4(0.0,0.0,0.0,0.0);
              highp vec2 d=2.0*coord-vec2(1.0,1.0);
              highp float r=length(d);
              if (0.25<=r && r<=0.75) {
                highp float a=atan2(d.x,-d.y);
                if (angleBase<=a && a<=angle) {
                  highp float p=(a-angleBase)/(angle-angleBase);
                  gl_FragColor = vec4(0.0,0.0,p,p) * qt_Opacity;
                }
              }
            }"
        }
      
        // Animate the gauge position
        SequentialAnimation {
          running: true
          loops: Animation.Infinite
          NumberAnimation {
            from: gauge.angleBase
            to: gauge.angleBase+1.5*gauge.pi
            duration: 1000
            target: gauge
            property: 'angle'
            easing.type: Easing.InOutSine
          }
          NumberAnimation {
            from: gauge.angleBase+1.5*gauge.pi
            to: gauge.angleBase
            duration: 1000
            target: gauge
            property: 'angle'
            easing.type: Easing.InOutSine
          }
        }
      }
      

      Runs in 5.10.1's qmlscene but no reason it shouldn't work in older versions.

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jars121
        wrote on last edited by
        #3

        That looks like exactly what I'm after! Thanks for bringing this functionality to my attention!

        I'll give it a go this evening and report back with any issues.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jars121
          wrote on last edited by
          #4

          I've taken the exact code presented above and am receiving the following compilation errors:

          QOpenGLShader::compile(Fragment): ERROR: 0:12: Invalid call of undeclared identifier 'atan2'
          ERROR: 0:13: Use of undeclared identifier 'a'
          ERROR: 0:13: Use of undeclared identifier 'a'
          ERROR: 0:14: Use of undeclared identifier 'a'
          ERROR: 0:15: Use of undeclared identifier 'p'
          ERROR: 0:15: Use of undeclared identifier 'p'
          
          *** Problematic Fragment shader source code ***
          #define lowp
          #define mediump
          #define highp
          #line 1
           
                                    uniform lowp float qt_Opacity; 
                                    uniform highp float angleBase; 
                                    uniform highp float angle; 
                                    varying highp vec2 coord; 
                                    void main() { 
                                      gl_FragColor = vec4(0.0,0.0,0.0,0.0); 
                                      highp vec2 d=2.0*coord-vec2(1.0,1.0); 
                                      highp float r=length(d); 
                                      if (0.25<=r && r<=0.75) { 
                                        highp float a=atan2(d.x,-d.y); 
                                        if (angleBase<=a && a<=angle) { 
                                          highp float p=(a-angleBase)/(angle-angleBase); 
                                          gl_FragColor = vec4(0.0,0.0,p,p) * qt_Opacity; 
                                        } 
                                      } 
                                    }
          
          ***
          QQuickCustomMaterialShader: Shader compilation failed:
          "ERROR: 0:12: Invalid call of undeclared identifier 'atan2'\nERROR: 0:13: Use of undeclared identifier 'a'\nERROR: 0:13: Use of undeclared identifier 'a'\nERROR: 0:14: Use of undeclared identifier 'a'\nERROR: 0:15: Use of undeclared identifier 'p'\nERROR: 0:15: Use of undeclared identifier 'p'\n"
          

          I've never worked with OpenGL before so am struggling somewhat to make sense of the above.

          raven-worxR 1 Reply Last reply
          0
          • J jars121

            I've taken the exact code presented above and am receiving the following compilation errors:

            QOpenGLShader::compile(Fragment): ERROR: 0:12: Invalid call of undeclared identifier 'atan2'
            ERROR: 0:13: Use of undeclared identifier 'a'
            ERROR: 0:13: Use of undeclared identifier 'a'
            ERROR: 0:14: Use of undeclared identifier 'a'
            ERROR: 0:15: Use of undeclared identifier 'p'
            ERROR: 0:15: Use of undeclared identifier 'p'
            
            *** Problematic Fragment shader source code ***
            #define lowp
            #define mediump
            #define highp
            #line 1
             
                                      uniform lowp float qt_Opacity; 
                                      uniform highp float angleBase; 
                                      uniform highp float angle; 
                                      varying highp vec2 coord; 
                                      void main() { 
                                        gl_FragColor = vec4(0.0,0.0,0.0,0.0); 
                                        highp vec2 d=2.0*coord-vec2(1.0,1.0); 
                                        highp float r=length(d); 
                                        if (0.25<=r && r<=0.75) { 
                                          highp float a=atan2(d.x,-d.y); 
                                          if (angleBase<=a && a<=angle) { 
                                            highp float p=(a-angleBase)/(angle-angleBase); 
                                            gl_FragColor = vec4(0.0,0.0,p,p) * qt_Opacity; 
                                          } 
                                        } 
                                      }
            
            ***
            QQuickCustomMaterialShader: Shader compilation failed:
            "ERROR: 0:12: Invalid call of undeclared identifier 'atan2'\nERROR: 0:13: Use of undeclared identifier 'a'\nERROR: 0:13: Use of undeclared identifier 'a'\nERROR: 0:14: Use of undeclared identifier 'a'\nERROR: 0:15: Use of undeclared identifier 'p'\nERROR: 0:15: Use of undeclared identifier 'p'\n"
            

            I've never worked with OpenGL before so am struggling somewhat to make sense of the above.

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            @jars121
            why not simply use a conical gradient? (In conjunction with a opacity mask)

            --- 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
            0
            • J Offline
              J Offline
              jars121
              wrote on last edited by
              #6

              @raven-worx that certainly appears to be simpler! I'll have a play with that approach now and report back, thanks!

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jars121
                wrote on last edited by
                #7

                @raven-worx Thanks again, I've got it working almost 100% now!

                Quick question, is there a way to limit/stop the ConicalMask? At the moment the OpacityMask is working nicely, but when the needle is at very low values, the ConicalMask actually appears on the other side of the gauge! I can combat this by shortening the Gradient Stop, but I'd like to have a longer GradientStop, and simply 'turn off' the ConicalGradient at a certain value/angle.

                raven-worxR 1 Reply Last reply
                0
                • J jars121

                  @raven-worx Thanks again, I've got it working almost 100% now!

                  Quick question, is there a way to limit/stop the ConicalMask? At the moment the OpacityMask is working nicely, but when the needle is at very low values, the ConicalMask actually appears on the other side of the gauge! I can combat this by shortening the Gradient Stop, but I'd like to have a longer GradientStop, and simply 'turn off' the ConicalGradient at a certain value/angle.

                  raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by
                  #8

                  @jars121
                  i don't quite understand your remaining issue.
                  But i think everything should be achievable by setting the gradient stops properly and/or the opacity mask.

                  --- 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
                  0
                  • mranger90M Offline
                    mranger90M Offline
                    mranger90
                    wrote on last edited by
                    #9

                    I got this working by changing the atan2 calls in the fragment shader to atan.
                    This was on an ubunut 16.04 system in a VM.

                    timdayT 1 Reply Last reply
                    2
                    • mranger90M mranger90

                      I got this working by changing the atan2 calls in the fragment shader to atan.
                      This was on an ubunut 16.04 system in a VM.

                      timdayT Offline
                      timdayT Offline
                      timday
                      wrote on last edited by timday
                      #10

                      @mranger90 Oops sorry for causing confusion... I was on a system with an Nvidia card (and running Debian) when I threw the ShaderEffect version together... and it seems Nvidia do provide an atan2 in their GLSL compiler (perhaps because their old "Cg" precursor language used to have it). Didn't try it anywhere else. GLSL's regular atan with two arguments does indeed seem to do the same thing.

                      Have to admit I'd completely forgotten about ConicalGradient! I do like ShaderEffect though... it's QML's magic wand... you can do some really nifty stuff with it e,g https://youtu.be/FM0CbKvYpYI or https://youtu.be/BuTYBBScfMo or https://forum.qt.io/topic/84532/qml-animation-trail-on-object/2 ...

                      1 Reply Last reply
                      0
                      • PientashekP Offline
                        PientashekP Offline
                        Pientashek
                        wrote on last edited by
                        #11

                        @jars121 Could you put a sample code on how to get this effect using OpacistyMask and ConicalGradient? I am trying to implement this effect but with a poor result..

                        1 Reply Last reply
                        0

                        • Login

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