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. [Solved] Drawing Linear graph using QML canvas
QtWS25 Last Chance

[Solved] Drawing Linear graph using QML canvas

Scheduled Pinned Locked Moved QML and Qt Quick
qml canvasqmlgraphchart
18 Posts 2 Posters 9.4k 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.
  • vishnuV Offline
    vishnuV Offline
    vishnu
    wrote on last edited by vishnu
    #1

    I need to draw a boundary graph and then update the current position of the machine (x,y,z posistions comes from cpp side) on the boundary graph. looks like this.
    All i did is this. drawn x and y axis and the labels and small ticks. took some points and connected them. What is wrong is what i am showing on the xlabels in different to the values that i have plotted .There is no binding between them.All i need to show is a small rectangle with current position on it(which varies frequently.)as shown here. Any suggesion or hints will be really helpful. Thanks

    Item{
            id:root_chart
            //        anchors.fill: parent
            anchors.left: root_checkbox.right
            height: parent.height
            anchors.right: parent.right
            Canvas {
                id: chart
    
    
                property int maxPoints: 200
                property var xValues:[0,4,9,13,9,4,0]
                property var yValues: [0,3,3,0,-4,-4,0]
    
                anchors.fill: parent
                anchors.margins: 50
                antialiasing: true
                renderStrategy: Canvas.Cooperative
    
                property color linecolor: "#808080"
                property color background: "#f5f5f5"
    
                property int yRef: chart.height/2 - chart.xAxisHeight
                property int xRef: chart.yAxisWidth + 100
    
                property int yAxisWidth: 80   // x pos of y-axis in pixel
                property int xAxisHeight: 40  // y distance of x-axis from bottom in pixel
    
                property bool fillAreas: false
                property int scalingFactor: 30
    
                function drawAxis(ctx) {
                    var yAxis = {
                        labels: ["+6 dB", "0 dB", "-6 dB", "-12 dB", "-18 dB"],
                        lines: [0.0, 0.22, 0.44, 0.66, 0.88]
                    }
    
                    var xAxis = {
                        labels: ["100 mm", "150 mm", "200 mm", "250 mm", "300 mm",
                            "350 mm", "400 mm", "450 mm", "500 mm", "550 mm"],
                        lines: [0.0, 0.15, 0.25, 0.35, 0.50,
                            0.60, 0.70, 0.82, 0.92, 1.00]
                    }
    
                    var y0 = 50.0;
                    var y1 = chart.height - chart.xAxisHeight
                    var x0 = chart.yAxisWidth
                    var x1 = chart.width - 100
    
                    // clear
                    ctx.fillStyle = background
                    ctx.fillRect(0,0,width,height)
    
                    // frame
                    ctx.strokeStyle = linecolor;
                    ctx.fillStyle = "#999999";
                    ctx.lineWidth = 1
    
                    ctx.beginPath();
                    ctx.moveTo(x0,y0);
    
                    ctx.lineTo(x1,y0);
                    ctx.lineTo(x1,y1);
                    ctx.lineTo(x0,y1);
                    ctx.lineTo(x0,y0);
                    ctx.stroke()
    
                    var w
                    var yp
    
                    //drawing the small lines on the X and Y axis
                    for (var y = 0; y < yAxis.lines.length; y++)
                    {
                        ctx.beginPath();
                        ctx.strokeStyle = "black"
                        yp = (y1 - y0) * yAxis.lines[y] + y0
                        ctx.moveTo(x0 - 10, yp);
                        ctx.lineTo(x0, yp);
                        ctx.stroke();
                        ctx.closePath();
    
                        //                w = ctx.measureText(yAxis.labels[y]).width
                        //                ctx.fillText(yAxis.labels[y], x0 - w -5, yp + 5)
                    }
    
                    for (var x = 0; x < xAxis.lines.length; x++)
                    {
                        ctx.beginPath();
                        var xp = (x1 - x0) * xAxis.lines[x] + x0
                        ctx.moveTo(xp, y1);
                        ctx.lineTo(xp, y1 + 5);
                        ctx.stroke();
                        ctx.closePath();
    
                        ctx.fillText(xAxis.labels[x], xp - 20, y1 + 20)
                    }
                    // move to reference point
                    ctx.beginPath();
                    ctx.arc(xRef,yRef,1,0,2*Math.PI);
                    ctx.stroke();
                    ctx.closePath();
                    //move to points
                    ctx.beginPath();
                    ctx.moveTo(xRef,yRef);
                    for( var i=0;i< xValues.length;i++){
                        ctx.lineTo(xRef+(xValues[i]*scalingFactor),yRef+(yValues[i]*scalingFactor))
                    }
                    ctx.lineWidth = 2
                    ctx.stroke();
                    ctx.closePath();
    
                    var dx = (x1 - x0) / (maxPoints - 1)
                    var dy = (y1 - y0) / 50.0
                    ctx.beginPath();
                    //                ctx.arc(x0,y1 - data1[0] * dy,20,0,2*Math.PI);
                    //                ctx.fillStyle = "#FF0000";
    
                    //                ctx.stroke();
                    //                ctx.closePath();
                    ctx.moveTo(x0, y1 - data1[0] * dy)
                    // move to tool tip
                    for( var i=0;i<data1.length;i++){
                        //moving y position
                        yp = y1 - data1[i] * dy;
                        ctx.lineTo(x0 + i * dx, yp)
                        ctx.stroke();
                    }
                }
                onPaint: {
                    var ctx = getContext("2d");
                    ctx.save();
                    drawAxis(ctx)
                    ctx.restore();
                }
            }
        }
    
    p3c0P 1 Reply Last reply
    0
    • vishnuV vishnu

      I need to draw a boundary graph and then update the current position of the machine (x,y,z posistions comes from cpp side) on the boundary graph. looks like this.
      All i did is this. drawn x and y axis and the labels and small ticks. took some points and connected them. What is wrong is what i am showing on the xlabels in different to the values that i have plotted .There is no binding between them.All i need to show is a small rectangle with current position on it(which varies frequently.)as shown here. Any suggesion or hints will be really helpful. Thanks

      Item{
              id:root_chart
              //        anchors.fill: parent
              anchors.left: root_checkbox.right
              height: parent.height
              anchors.right: parent.right
              Canvas {
                  id: chart
      
      
                  property int maxPoints: 200
                  property var xValues:[0,4,9,13,9,4,0]
                  property var yValues: [0,3,3,0,-4,-4,0]
      
                  anchors.fill: parent
                  anchors.margins: 50
                  antialiasing: true
                  renderStrategy: Canvas.Cooperative
      
                  property color linecolor: "#808080"
                  property color background: "#f5f5f5"
      
                  property int yRef: chart.height/2 - chart.xAxisHeight
                  property int xRef: chart.yAxisWidth + 100
      
                  property int yAxisWidth: 80   // x pos of y-axis in pixel
                  property int xAxisHeight: 40  // y distance of x-axis from bottom in pixel
      
                  property bool fillAreas: false
                  property int scalingFactor: 30
      
                  function drawAxis(ctx) {
                      var yAxis = {
                          labels: ["+6 dB", "0 dB", "-6 dB", "-12 dB", "-18 dB"],
                          lines: [0.0, 0.22, 0.44, 0.66, 0.88]
                      }
      
                      var xAxis = {
                          labels: ["100 mm", "150 mm", "200 mm", "250 mm", "300 mm",
                              "350 mm", "400 mm", "450 mm", "500 mm", "550 mm"],
                          lines: [0.0, 0.15, 0.25, 0.35, 0.50,
                              0.60, 0.70, 0.82, 0.92, 1.00]
                      }
      
                      var y0 = 50.0;
                      var y1 = chart.height - chart.xAxisHeight
                      var x0 = chart.yAxisWidth
                      var x1 = chart.width - 100
      
                      // clear
                      ctx.fillStyle = background
                      ctx.fillRect(0,0,width,height)
      
                      // frame
                      ctx.strokeStyle = linecolor;
                      ctx.fillStyle = "#999999";
                      ctx.lineWidth = 1
      
                      ctx.beginPath();
                      ctx.moveTo(x0,y0);
      
                      ctx.lineTo(x1,y0);
                      ctx.lineTo(x1,y1);
                      ctx.lineTo(x0,y1);
                      ctx.lineTo(x0,y0);
                      ctx.stroke()
      
                      var w
                      var yp
      
                      //drawing the small lines on the X and Y axis
                      for (var y = 0; y < yAxis.lines.length; y++)
                      {
                          ctx.beginPath();
                          ctx.strokeStyle = "black"
                          yp = (y1 - y0) * yAxis.lines[y] + y0
                          ctx.moveTo(x0 - 10, yp);
                          ctx.lineTo(x0, yp);
                          ctx.stroke();
                          ctx.closePath();
      
                          //                w = ctx.measureText(yAxis.labels[y]).width
                          //                ctx.fillText(yAxis.labels[y], x0 - w -5, yp + 5)
                      }
      
                      for (var x = 0; x < xAxis.lines.length; x++)
                      {
                          ctx.beginPath();
                          var xp = (x1 - x0) * xAxis.lines[x] + x0
                          ctx.moveTo(xp, y1);
                          ctx.lineTo(xp, y1 + 5);
                          ctx.stroke();
                          ctx.closePath();
      
                          ctx.fillText(xAxis.labels[x], xp - 20, y1 + 20)
                      }
                      // move to reference point
                      ctx.beginPath();
                      ctx.arc(xRef,yRef,1,0,2*Math.PI);
                      ctx.stroke();
                      ctx.closePath();
                      //move to points
                      ctx.beginPath();
                      ctx.moveTo(xRef,yRef);
                      for( var i=0;i< xValues.length;i++){
                          ctx.lineTo(xRef+(xValues[i]*scalingFactor),yRef+(yValues[i]*scalingFactor))
                      }
                      ctx.lineWidth = 2
                      ctx.stroke();
                      ctx.closePath();
      
                      var dx = (x1 - x0) / (maxPoints - 1)
                      var dy = (y1 - y0) / 50.0
                      ctx.beginPath();
                      //                ctx.arc(x0,y1 - data1[0] * dy,20,0,2*Math.PI);
                      //                ctx.fillStyle = "#FF0000";
      
                      //                ctx.stroke();
                      //                ctx.closePath();
                      ctx.moveTo(x0, y1 - data1[0] * dy)
                      // move to tool tip
                      for( var i=0;i<data1.length;i++){
                          //moving y position
                          yp = y1 - data1[i] * dy;
                          ctx.lineTo(x0 + i * dx, yp)
                          ctx.stroke();
                      }
                  }
                  onPaint: {
                      var ctx = getContext("2d");
                      ctx.save();
                      drawAxis(ctx)
                      ctx.restore();
                  }
              }
          }
      
      p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

      @vishnu Adding a Rectangle item and setting its x and y position should work. Set its z value greater than that of Canvas to bring it on top.

      157

      vishnuV 1 Reply Last reply
      1
      • p3c0P p3c0

        @vishnu Adding a Rectangle item and setting its x and y position should work. Set its z value greater than that of Canvas to bring it on top.

        vishnuV Offline
        vishnuV Offline
        vishnu
        wrote on last edited by vishnu
        #3

        @p3c0
        Thanks.It worked but i am not able to map the logical value to the screen pixel values. Since i binded the value to x and y of rectangle, It looks different in different platforms. What i mean to say is the values i get from cpp varies from -1500 to +1500. Now How can i map the logical value to x,y, pixels of various screen sizes? Thanks

        p3c0P 1 Reply Last reply
        0
        • vishnuV vishnu

          @p3c0
          Thanks.It worked but i am not able to map the logical value to the screen pixel values. Since i binded the value to x and y of rectangle, It looks different in different platforms. What i mean to say is the values i get from cpp varies from -1500 to +1500. Now How can i map the logical value to x,y, pixels of various screen sizes? Thanks

          p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #4

          @vishnu Try mapToItem.

          157

          vishnuV 1 Reply Last reply
          0
          • p3c0P p3c0

            @vishnu Try mapToItem.

            vishnuV Offline
            vishnuV Offline
            vishnu
            wrote on last edited by
            #5

            @p3c0
            I didn't really get how to use it so I wrote my own function to map them

            function map(value,srcMax,srcMin,dstMax,dstMin){
                    console.log(srcMax,srcMin,dstMax,dstMin," value ",value)
                    return Number(((((dstMax - dstMin)*(value - srcMin)/(srcMax - srcMin))+dstMin)).toFixed(1)) ;
                }
            

            I hope it will be useful for someone. one more question. I have drawn the graph assuming positive axis of X to the right(like standard one). How can make it to the left.As shown in here

            p3c0P 1 Reply Last reply
            0
            • vishnuV vishnu

              @p3c0
              I didn't really get how to use it so I wrote my own function to map them

              function map(value,srcMax,srcMin,dstMax,dstMin){
                      console.log(srcMax,srcMin,dstMax,dstMin," value ",value)
                      return Number(((((dstMax - dstMin)*(value - srcMin)/(srcMax - srcMin))+dstMin)).toFixed(1)) ;
                  }
              

              I hope it will be useful for someone. one more question. I have drawn the graph assuming positive axis of X to the right(like standard one). How can make it to the left.As shown in here

              p3c0P Offline
              p3c0P Offline
              p3c0
              Moderators
              wrote on last edited by
              #6

              @vishnu Using negative x value while drawing ? Passing negative values to lineTo or moveTo from point of origin should work.

              157

              vishnuV 1 Reply Last reply
              0
              • p3c0P p3c0

                @vishnu Using negative x value while drawing ? Passing negative values to lineTo or moveTo from point of origin should work.

                vishnuV Offline
                vishnuV Offline
                vishnu
                wrote on last edited by vishnu
                #7

                @p3c0
                I got a new error
                Cannot read property 'length' of undefined
                I have defined the properties like this

                 property var physicalValue_x: []
                    property var physicalValue_z: []
                    property var logicalValue_x: [-80,-40,40,80,220,400,740,680,170,-170,-250,-220,-80,-40,-20]
                    property var logicalValue_z: [820,820,820,820,780,670,560,305,295,285,380,780,820,820,820]
                
                function map(value,srcMax,srcMin,dstMax,dstMin){
                        //        console.log(srcMax,srcMin,dstMax,dstMin," value ",value)
                        return Number(((((dstMax - dstMin)*(value - srcMin)/(srcMax - srcMin))+dstMin)).toFixed(1)) ;
                    }
                
                    function logicalToPhysical()
                    {
                //        if(root.physicalValue_x)
                        for(var i=0;i<logicalValue_z.length;i++)//error 'length undefined'
                        {
                            var pos_x = root.map(logicalValue_x[i],maxRange_x,minRange_x,x1,x0)
                            physicalValue_x[i] = pos_x
                            var pos_z = root.map(logicalValue_z[i],maxRange_z,minRange_z,y1,y0)
                            physicalValue_z[i] = pos_z // here type error
                        }
                        console.log("physical x values"+physicalValue_x)
                        console.log("physical z values"+physicalValue_z)
                    }
                

                if i uncomment the checkif(root.physicalValue_x) i get the error at for loop Cannot read property 'length' of undefined.
                If I comment it i get 'TypeError: Type error' at physicalValue_z[i] = pos_z also 'TypeError: Cannot read property '0' of undefined' at var pos_z. I think the properties are not instantiated properly but eventually they will. What is the best practice to avoid these errors. Thanks

                p3c0P 1 Reply Last reply
                0
                • vishnuV vishnu

                  @p3c0
                  I got a new error
                  Cannot read property 'length' of undefined
                  I have defined the properties like this

                   property var physicalValue_x: []
                      property var physicalValue_z: []
                      property var logicalValue_x: [-80,-40,40,80,220,400,740,680,170,-170,-250,-220,-80,-40,-20]
                      property var logicalValue_z: [820,820,820,820,780,670,560,305,295,285,380,780,820,820,820]
                  
                  function map(value,srcMax,srcMin,dstMax,dstMin){
                          //        console.log(srcMax,srcMin,dstMax,dstMin," value ",value)
                          return Number(((((dstMax - dstMin)*(value - srcMin)/(srcMax - srcMin))+dstMin)).toFixed(1)) ;
                      }
                  
                      function logicalToPhysical()
                      {
                  //        if(root.physicalValue_x)
                          for(var i=0;i<logicalValue_z.length;i++)//error 'length undefined'
                          {
                              var pos_x = root.map(logicalValue_x[i],maxRange_x,minRange_x,x1,x0)
                              physicalValue_x[i] = pos_x
                              var pos_z = root.map(logicalValue_z[i],maxRange_z,minRange_z,y1,y0)
                              physicalValue_z[i] = pos_z // here type error
                          }
                          console.log("physical x values"+physicalValue_x)
                          console.log("physical z values"+physicalValue_z)
                      }
                  

                  if i uncomment the checkif(root.physicalValue_x) i get the error at for loop Cannot read property 'length' of undefined.
                  If I comment it i get 'TypeError: Type error' at physicalValue_z[i] = pos_z also 'TypeError: Cannot read property '0' of undefined' at var pos_z. I think the properties are not instantiated properly but eventually they will. What is the best practice to avoid these errors. Thanks

                  p3c0P Offline
                  p3c0P Offline
                  p3c0
                  Moderators
                  wrote on last edited by
                  #8

                  @vishnu This means it is out of its scope. Access logicalValue_z just like you accessed physicalValue_x using root.

                  157

                  vishnuV 1 Reply Last reply
                  0
                  • p3c0P p3c0

                    @vishnu This means it is out of its scope. Access logicalValue_z just like you accessed physicalValue_x using root.

                    vishnuV Offline
                    vishnuV Offline
                    vishnu
                    wrote on last edited by
                    #9

                    @p3c0
                    As you said i have changed like this

                     function logicalToPhysical()
                        {
                    //        if(root.physicalValue_x)
                            for(var i=0;i<root.logicalValue_x.length;i++)
                            {
                                var pos_x = root.map(root.logicalValue_x[i],root.maxRange_x,root.minRange_x,root.x1,root.x0)
                                root.physicalValue_x[i] = pos_x
                                var pos_z = root.map(root.logicalValue_z[i],root.maxRange_z,root.minRange_z,root.y1,root.y0) // here is the error
                                root.physicalValue_z[i] = pos_z
                            }
                            console.log("physical x values"+root.physicalValue_x)
                            console.log("physical z values"+root.physicalValue_z)
                        }
                    

                    But still the error TypeError: Cannot read property '0' of undefined at var pos_z;
                    FIY:these are the properties in addition to above properties

                      property real y0 : 50.0;
                        property real y1 : chart.height - chart.xAxisHeight
                        property real x0 : chart.yAxisWidth
                        property real x1 : chart.width - 100
                    
                    p3c0P 1 Reply Last reply
                    0
                    • vishnuV vishnu

                      @p3c0
                      As you said i have changed like this

                       function logicalToPhysical()
                          {
                      //        if(root.physicalValue_x)
                              for(var i=0;i<root.logicalValue_x.length;i++)
                              {
                                  var pos_x = root.map(root.logicalValue_x[i],root.maxRange_x,root.minRange_x,root.x1,root.x0)
                                  root.physicalValue_x[i] = pos_x
                                  var pos_z = root.map(root.logicalValue_z[i],root.maxRange_z,root.minRange_z,root.y1,root.y0) // here is the error
                                  root.physicalValue_z[i] = pos_z
                              }
                              console.log("physical x values"+root.physicalValue_x)
                              console.log("physical z values"+root.physicalValue_z)
                          }
                      

                      But still the error TypeError: Cannot read property '0' of undefined at var pos_z;
                      FIY:these are the properties in addition to above properties

                        property real y0 : 50.0;
                          property real y1 : chart.height - chart.xAxisHeight
                          property real x0 : chart.yAxisWidth
                          property real x1 : chart.width - 100
                      
                      p3c0P Offline
                      p3c0P Offline
                      p3c0
                      Moderators
                      wrote on last edited by
                      #10

                      @vishnu Did Cannot read property 'length' of undefined for logicalValue_z go ?
                      For the other check which of the other properties is not accessible.

                      157

                      vishnuV 1 Reply Last reply
                      0
                      • p3c0P p3c0

                        @vishnu Did Cannot read property 'length' of undefined for logicalValue_z go ?
                        For the other check which of the other properties is not accessible.

                        vishnuV Offline
                        vishnuV Offline
                        vishnu
                        wrote on last edited by
                        #11

                        @p3c0
                        Nope. if put the check if(root.physicalValue_x). The error TypeError: Cannot read property 'length' of undefined still appears at for(var i=0;i<root.logicalValue_x.length;i++).If I dont put the check then i get TypeError: Cannot read property '0' of undefined at var pos_z = root.map(root.logicalValue_z[i],root.maxRange_z,root.minRange_z,root.y1,root.y0).

                        p3c0P 1 Reply Last reply
                        0
                        • vishnuV vishnu

                          @p3c0
                          Nope. if put the check if(root.physicalValue_x). The error TypeError: Cannot read property 'length' of undefined still appears at for(var i=0;i<root.logicalValue_x.length;i++).If I dont put the check then i get TypeError: Cannot read property '0' of undefined at var pos_z = root.map(root.logicalValue_z[i],root.maxRange_z,root.minRange_z,root.y1,root.y0).

                          p3c0P Offline
                          p3c0P Offline
                          p3c0
                          Moderators
                          wrote on last edited by
                          #12

                          @vishnu Can you post a minimal example which replicates above scenario ? Something is not clear here.

                          157

                          vishnuV 1 Reply Last reply
                          0
                          • p3c0P p3c0

                            @vishnu Can you post a minimal example which replicates above scenario ? Something is not clear here.

                            vishnuV Offline
                            vishnuV Offline
                            vishnu
                            wrote on last edited by
                            #13

                            @p3c0
                            okay.

                            Rectangle {
                                id: root
                                width: 1280; height: 800
                                property var physicalValue_x: []
                                property var physicalValue_z: []
                                property var logicalValue_x: [-80,-40,40,80,220,400,740,680,170,-170,-250,-220,-80,-40,-20]
                                property var logicalValue_z: [820,820,820,820,780,670,560,305,295,285,380,780,820,820,820]
                            
                                property int maxRange_x: 1040
                                property int minRange_x: -400
                                property int maxRange_z: 1020
                                property int minRange_z: 100
                                property real y0 : 50.0;
                                property real y1 : chart.height - chart.xAxisHeight
                                property real x0 : chart.yAxisWidth
                                property real x1 : chart.width - 100
                            
                                function map(value,srcMax,srcMin,dstMax,dstMin){
                                    return Number(((((dstMax - dstMin)*(value - srcMin)/(srcMax - srcMin))+dstMin)).toFixed(1)) ;
                                }
                            
                                function logicalToPhysical()
                                {
                                    for(var i=0;i<root.logicalValue_x.length;i++)
                                    {
                                        var pos_x = root.map(root.logicalValue_x[i],root.maxRange_x,root.minRange_x,root.x1,root.x0)
                                        root.physicalValue_x[i] = pos_x
                                        var pos_z = root.map(root.logicalValue_z[i],root.maxRange_z,root.minRange_z,root.y1,root.y0)
                                        root.physicalValue_z[i] = pos_z
                                    }
                                    console.log("physical x values"+root.physicalValue_x)
                                    console.log("physical z values"+root.physicalValue_z)
                                }
                            Item{
                                    id:root_chart
                                    //        anchors.fill: parent
                                    anchors.left: root_checkbox.right
                                    height: parent.height
                                    anchors.right: parent.right
                                    Canvas {
                                        id: chart
                                        property int maxPoints: 200
                                        Component.onCompleted: {
                                            logicalToPhysical();/
                                        }
                                    onWidthChanged: {
                                            console.log("chart width is changing ")
                                            logicalToPhysical() //call 1 
                                            requestPaint()
                                        }
                                        onHeightChanged: {
                                            console.log("chart height is changing ")
                                            logicalToPhysical()// call 2
                                            requestPaint()
                                        }
                                 }
                            

                            I found that because of these calls 1 and 2 the error is coming.

                            p3c0P 1 Reply Last reply
                            0
                            • vishnuV vishnu

                              @p3c0
                              okay.

                              Rectangle {
                                  id: root
                                  width: 1280; height: 800
                                  property var physicalValue_x: []
                                  property var physicalValue_z: []
                                  property var logicalValue_x: [-80,-40,40,80,220,400,740,680,170,-170,-250,-220,-80,-40,-20]
                                  property var logicalValue_z: [820,820,820,820,780,670,560,305,295,285,380,780,820,820,820]
                              
                                  property int maxRange_x: 1040
                                  property int minRange_x: -400
                                  property int maxRange_z: 1020
                                  property int minRange_z: 100
                                  property real y0 : 50.0;
                                  property real y1 : chart.height - chart.xAxisHeight
                                  property real x0 : chart.yAxisWidth
                                  property real x1 : chart.width - 100
                              
                                  function map(value,srcMax,srcMin,dstMax,dstMin){
                                      return Number(((((dstMax - dstMin)*(value - srcMin)/(srcMax - srcMin))+dstMin)).toFixed(1)) ;
                                  }
                              
                                  function logicalToPhysical()
                                  {
                                      for(var i=0;i<root.logicalValue_x.length;i++)
                                      {
                                          var pos_x = root.map(root.logicalValue_x[i],root.maxRange_x,root.minRange_x,root.x1,root.x0)
                                          root.physicalValue_x[i] = pos_x
                                          var pos_z = root.map(root.logicalValue_z[i],root.maxRange_z,root.minRange_z,root.y1,root.y0)
                                          root.physicalValue_z[i] = pos_z
                                      }
                                      console.log("physical x values"+root.physicalValue_x)
                                      console.log("physical z values"+root.physicalValue_z)
                                  }
                              Item{
                                      id:root_chart
                                      //        anchors.fill: parent
                                      anchors.left: root_checkbox.right
                                      height: parent.height
                                      anchors.right: parent.right
                                      Canvas {
                                          id: chart
                                          property int maxPoints: 200
                                          Component.onCompleted: {
                                              logicalToPhysical();/
                                          }
                                      onWidthChanged: {
                                              console.log("chart width is changing ")
                                              logicalToPhysical() //call 1 
                                              requestPaint()
                                          }
                                          onHeightChanged: {
                                              console.log("chart height is changing ")
                                              logicalToPhysical()// call 2
                                              requestPaint()
                                          }
                                   }
                              

                              I found that because of these calls 1 and 2 the error is coming.

                              p3c0P Offline
                              p3c0P Offline
                              p3c0
                              Moderators
                              wrote on last edited by p3c0
                              #14

                              @vishnu This doesnot show any error specific to what you posted earlier.

                              157

                              vishnuV 1 Reply Last reply
                              0
                              • p3c0P p3c0

                                @vishnu This doesnot show any error specific to what you posted earlier.

                                vishnuV Offline
                                vishnuV Offline
                                vishnu
                                wrote on last edited by vishnu
                                #15

                                @p3c0
                                I think i better post the whole file. sorry for the inconvenience.

                                import QtQuick 2.4
                                import QtQuick.Controls 1.2
                                Rectangle {
                                    id: root
                                    width: 1280; height: 800
                                
                                    property variant data1: [20.0]
                                    property double currentPos_x:591
                                    property double currentPos_y:60
                                    property double currentPos_z:193
                                
                                    property var physicalValue_x: []
                                    property var physicalValue_z: []
                                    property var logicalValue_x: [-80,-40,40,80,220,400,740,680,170,-170,-250,-220,-80,-40,-20]
                                    property var logicalValue_z: [820,820,820,820,780,670,560,305,295,285,380,780,820,820,820]
                                
                                    property double showPos_x
                                    property double showPos_y
                                    property double showPos_z
                                
                                
                                    property int maxRange_x: 1040
                                    property int minRange_x: -400
                                    property int maxRange_z: 1020
                                    property int minRange_z: 100
                                    property real y0 : 50.0;
                                    property real y1 : chart.height - chart.xAxisHeight
                                    property real x0 : chart.yAxisWidth
                                    property real x1 : chart.width - 100
                                
                                    function map(value,srcMax,srcMin,dstMax,dstMin){
                                        //        console.log(srcMax,srcMin,dstMax,dstMin," value ",value)
                                        return Number(((((dstMax - dstMin)*(value - srcMin)/(srcMax - srcMin))+dstMin)).toFixed(1)) ;
                                    }
                                
                                    function logicalToPhysical()
                                    {
                                        for(var i=0;i<root.logicalValue_x.length;i++)
                                        {
                                            var pos_x = root.map(root.logicalValue_x[i],root.maxRange_x,root.minRange_x,root.x1,root.x0)
                                            root.physicalValue_x[i] = pos_x
                                            var pos_z = root.map(root.logicalValue_z[i],root.maxRange_z,root.minRange_z,root.y1,root.y0)
                                            root.physicalValue_z[i] = pos_z
                                        }
                                        console.log("physical x values"+root.physicalValue_x)
                                        console.log("physical z values"+root.physicalValue_z)
                                    }
                                
                                    function inputToGraph(byteIndex,bitIndex,bitValue){
                                
                                        if(bitIndex === -1){
                                            if(byteIndex === 36){
                                                //update x position
                                                showPos_x=Number((bitValue/1000).toFixed(1));
                                                var pos_x= root.map(bitValue/1000,maxRange_x,minRange_x,x1,x0);
                                                currentPos_x=pos_x;
                                //                console.log("current pos x map value"+currentPos_x)
                                            }
                                            if(byteIndex === 40){
                                                //update y position
                                                showPos_y=Number((bitValue/1000).toFixed(1));
                                                currentPos_y=bitValue/1000;
                                                //                console.log("current pos y map value"+currentPos_y)
                                            }
                                            if(byteIndex === 44){
                                                //update z position
                                                showPos_z=Number((bitValue/1000).toFixed(1));
                                                var pos_z= root.map(bitValue/1000,maxRange_z,minRange_z,y1,y0);
                                                currentPos_z=pos_z;
                                //                console.log("current pos z map value"+currentPos_z)
                                            }
                                        }
                                    }
                                
                                    Connections{
                                        target: tcpCommunicationPort
                                        onDataFromCpp:{
                                            inputToGraph(byteIndex,bitIndex,bitValue)
                                        }
                                    }
                                    Rectangle{
                                        id:root_checkbox
                                        anchors.left: parent.left
                                        width: parent.width/4
                                        height: parent.height
                                        Row{
                                            spacing: 50
                                            anchors.centerIn: parent
                                            Rectangle{
                                                width: triggerButton.width
                                                height: triggerButton.height
                                                border.color: "red"
                                                TextInput{
                                                    id: timeInput
                                                    anchors.centerIn: parent
                                                }
                                            }
                                            Button{
                                                id:triggerButton
                                                text:"trigger"
                                                onClicked: {
                                                    //                    var y0 = 50.0;
                                                    //                    var y1 = chart.height - chart.xAxisHeight
                                                    //                    var x0 = chart.yAxisWidth
                                                    //                    var x1 = chart.width - 100
                                                    //                    var mappedzvalue = root.map(521,maxRange_x,minRange_x,x1,x0);
                                                    //                    //                                        point2.ypos = mappedzvalue
                                                    //                    var mappedxvalue = root.map(717,maxRange_z,minRange_z,y1,y0)
                                                    //                    //                                        point2.xpos =Number((mappedxvalue).toFixed(1))
                                                    //                    console.log("mapped z value",mappedzvalue)
                                                    //                    console.log("mapped x value",mappedxvalue)
                                                    inputToGraph(36,-1,0);
                                                    inputToGraph(44,-1,0);
                                                }
                                            }
                                            Button{
                                                id:triggerButton1
                                                text:"trigger1"
                                                onClicked: {
                                                    console.log(" current ")
                                                }
                                            }
                                        }
                                    }
                                
                                
                                    Item{
                                        id:root_chart
                                        //        anchors.fill: parent
                                        anchors.left: root_checkbox.right
                                        height: parent.height
                                        anchors.right: parent.right
                                        Canvas {
                                            id: chart
                                            property int maxPoints: 200
                                            Component.onCompleted: {
                                                logicalToPhysical();
                                            }
                                            onWidthChanged: {
                                                console.log("chart width is changing ")
                                                if(root.physicalValue_x){
                                                    logicalToPhysical()
                                                    requestPaint()
                                                }
                                            }
                                            onHeightChanged: {
                                                console.log("chart height is changing ")
                                                logicalToPhysical()
                                                requestPaint()
                                            }
                                
                                            width: parent.width
                                            height: parent.height
                                            anchors.margins: 50
                                            antialiasing: true
                                            renderStrategy: Canvas.Cooperative
                                
                                            property color linecolor: "#808080"
                                            property color background: "#f5f5f5"
                                
                                            //            property int yRef: chart.height/2 - chart.xAxisHeight
                                            //            property int xRef: chart.yAxisWidth + 100
                                
                                            property int yAxisWidth: 80   // x pos of y-axis in pixel
                                            property int xAxisHeight: 40  // y distance of x-axis from bottom in pixel
                                
                                            property bool fillAreas: false
                                            property int scalingFactor: 30
                                
                                            function drawAxis(ctx) {
                                                var yAxis = {
                                                    labels: ["+6 dB", "0 dB", "-6 dB", "-12 dB", "-18 dB"],
                                                    lines: [0.0, 0.22, 0.44, 0.66, 0.88]
                                                }
                                
                                                var xAxis = {
                                                    labels: ["100 mm", "150 mm", "200 mm", "250 mm", "300 mm",
                                                        "350 mm", "400 mm", "450 mm", "500 mm", "550 mm"],
                                                    lines: [0.0, 0.15, 0.25, 0.35, 0.50,
                                                        0.60, 0.70, 0.82, 0.92, 1.00]
                                                }
                                
                                                //                var y0 = 50.0;
                                                //                var y1 = chart.height - chart.xAxisHeight
                                                //                var x0 = chart.yAxisWidth
                                                //                var x1 = chart.width - 100
                                
                                                // clear
                                                ctx.fillStyle = background
                                                ctx.fillRect(0,0,width,height)
                                
                                                // frame
                                                ctx.strokeStyle = linecolor;
                                                ctx.fillStyle = "#999999";
                                                ctx.lineWidth = 1
                                
                                                ctx.beginPath();
                                                ctx.moveTo(x0,y0);
                                
                                                ctx.lineTo(x1,y0);
                                                ctx.lineTo(x1,y1);
                                                ctx.lineTo(x0,y1);
                                                ctx.lineTo(x0,y0);
                                                ctx.stroke()
                                
                                                var w
                                                var yp
                                
                                                //drawing the small lines on the X and Y axis
                                                for (var y = 0; y < yAxis.lines.length; y++)
                                                {
                                                    ctx.beginPath();
                                                    ctx.strokeStyle = "black"
                                                    yp = (y1 - y0) * yAxis.lines[y] + y0
                                                    ctx.moveTo(x0 - 10, yp);
                                                    ctx.lineTo(x0, yp);
                                                    ctx.stroke();
                                                    ctx.closePath();
                                
                                                    //                w = ctx.measureText(yAxis.labels[y]).width
                                                    //                ctx.fillText(yAxis.labels[y], x0 - w -5, yp + 5)
                                                }
                                
                                                for (var x = 0; x < xAxis.lines.length; x++)
                                                {
                                                    ctx.beginPath();
                                                    var xp = (x1 - x0) * xAxis.lines[x] + x0
                                                    ctx.moveTo(xp, y1);
                                                    ctx.lineTo(xp, y1 + 5);
                                                    ctx.stroke();
                                                    ctx.closePath();
                                
                                                    ctx.fillText(xAxis.labels[x], xp - 20, y1 + 20)
                                                }
                                                ctx.beginPath();
                                                console.log("drawing the graph")
                                                console.log("chart width"+ chart.width);
                                
                                                ctx.moveTo(physicalValue_x[0],physicalValue_z[0]);
                                                for( var i=1;i< physicalValue_x.length;i++){
                                                    ctx.lineTo(physicalValue_x[i],physicalValue_z[i])
                                                }
                                                ctx.lineWidth = 2
                                                ctx.stroke();
                                                ctx.closePath();
                                            }
                                            onPaint: {
                                                var ctx = getContext("2d");
                                                //                ctx.save();
                                                drawAxis(ctx)
                                                //                ctx.restore();
                                            }
                                        }
                                        Rectangle {
                                            id: point1
                                            x: currentPos_x
                                            y: currentPos_z
                                            z:10
                                            radius: 5
                                            width: 60; height: 15
                                            color: "#800096d6"
                                            Text{
                                                id:currentpoisionText
                                                anchors.centerIn: parent
                                                text: showPos_x+","+showPos_z
                                            }
                                        }
                                    }
                                }
                                

                                try to ignore the function inputToGraph and connections because it is from cpp side.

                                p3c0P 1 Reply Last reply
                                0
                                • vishnuV vishnu

                                  @p3c0
                                  I think i better post the whole file. sorry for the inconvenience.

                                  import QtQuick 2.4
                                  import QtQuick.Controls 1.2
                                  Rectangle {
                                      id: root
                                      width: 1280; height: 800
                                  
                                      property variant data1: [20.0]
                                      property double currentPos_x:591
                                      property double currentPos_y:60
                                      property double currentPos_z:193
                                  
                                      property var physicalValue_x: []
                                      property var physicalValue_z: []
                                      property var logicalValue_x: [-80,-40,40,80,220,400,740,680,170,-170,-250,-220,-80,-40,-20]
                                      property var logicalValue_z: [820,820,820,820,780,670,560,305,295,285,380,780,820,820,820]
                                  
                                      property double showPos_x
                                      property double showPos_y
                                      property double showPos_z
                                  
                                  
                                      property int maxRange_x: 1040
                                      property int minRange_x: -400
                                      property int maxRange_z: 1020
                                      property int minRange_z: 100
                                      property real y0 : 50.0;
                                      property real y1 : chart.height - chart.xAxisHeight
                                      property real x0 : chart.yAxisWidth
                                      property real x1 : chart.width - 100
                                  
                                      function map(value,srcMax,srcMin,dstMax,dstMin){
                                          //        console.log(srcMax,srcMin,dstMax,dstMin," value ",value)
                                          return Number(((((dstMax - dstMin)*(value - srcMin)/(srcMax - srcMin))+dstMin)).toFixed(1)) ;
                                      }
                                  
                                      function logicalToPhysical()
                                      {
                                          for(var i=0;i<root.logicalValue_x.length;i++)
                                          {
                                              var pos_x = root.map(root.logicalValue_x[i],root.maxRange_x,root.minRange_x,root.x1,root.x0)
                                              root.physicalValue_x[i] = pos_x
                                              var pos_z = root.map(root.logicalValue_z[i],root.maxRange_z,root.minRange_z,root.y1,root.y0)
                                              root.physicalValue_z[i] = pos_z
                                          }
                                          console.log("physical x values"+root.physicalValue_x)
                                          console.log("physical z values"+root.physicalValue_z)
                                      }
                                  
                                      function inputToGraph(byteIndex,bitIndex,bitValue){
                                  
                                          if(bitIndex === -1){
                                              if(byteIndex === 36){
                                                  //update x position
                                                  showPos_x=Number((bitValue/1000).toFixed(1));
                                                  var pos_x= root.map(bitValue/1000,maxRange_x,minRange_x,x1,x0);
                                                  currentPos_x=pos_x;
                                  //                console.log("current pos x map value"+currentPos_x)
                                              }
                                              if(byteIndex === 40){
                                                  //update y position
                                                  showPos_y=Number((bitValue/1000).toFixed(1));
                                                  currentPos_y=bitValue/1000;
                                                  //                console.log("current pos y map value"+currentPos_y)
                                              }
                                              if(byteIndex === 44){
                                                  //update z position
                                                  showPos_z=Number((bitValue/1000).toFixed(1));
                                                  var pos_z= root.map(bitValue/1000,maxRange_z,minRange_z,y1,y0);
                                                  currentPos_z=pos_z;
                                  //                console.log("current pos z map value"+currentPos_z)
                                              }
                                          }
                                      }
                                  
                                      Connections{
                                          target: tcpCommunicationPort
                                          onDataFromCpp:{
                                              inputToGraph(byteIndex,bitIndex,bitValue)
                                          }
                                      }
                                      Rectangle{
                                          id:root_checkbox
                                          anchors.left: parent.left
                                          width: parent.width/4
                                          height: parent.height
                                          Row{
                                              spacing: 50
                                              anchors.centerIn: parent
                                              Rectangle{
                                                  width: triggerButton.width
                                                  height: triggerButton.height
                                                  border.color: "red"
                                                  TextInput{
                                                      id: timeInput
                                                      anchors.centerIn: parent
                                                  }
                                              }
                                              Button{
                                                  id:triggerButton
                                                  text:"trigger"
                                                  onClicked: {
                                                      //                    var y0 = 50.0;
                                                      //                    var y1 = chart.height - chart.xAxisHeight
                                                      //                    var x0 = chart.yAxisWidth
                                                      //                    var x1 = chart.width - 100
                                                      //                    var mappedzvalue = root.map(521,maxRange_x,minRange_x,x1,x0);
                                                      //                    //                                        point2.ypos = mappedzvalue
                                                      //                    var mappedxvalue = root.map(717,maxRange_z,minRange_z,y1,y0)
                                                      //                    //                                        point2.xpos =Number((mappedxvalue).toFixed(1))
                                                      //                    console.log("mapped z value",mappedzvalue)
                                                      //                    console.log("mapped x value",mappedxvalue)
                                                      inputToGraph(36,-1,0);
                                                      inputToGraph(44,-1,0);
                                                  }
                                              }
                                              Button{
                                                  id:triggerButton1
                                                  text:"trigger1"
                                                  onClicked: {
                                                      console.log(" current ")
                                                  }
                                              }
                                          }
                                      }
                                  
                                  
                                      Item{
                                          id:root_chart
                                          //        anchors.fill: parent
                                          anchors.left: root_checkbox.right
                                          height: parent.height
                                          anchors.right: parent.right
                                          Canvas {
                                              id: chart
                                              property int maxPoints: 200
                                              Component.onCompleted: {
                                                  logicalToPhysical();
                                              }
                                              onWidthChanged: {
                                                  console.log("chart width is changing ")
                                                  if(root.physicalValue_x){
                                                      logicalToPhysical()
                                                      requestPaint()
                                                  }
                                              }
                                              onHeightChanged: {
                                                  console.log("chart height is changing ")
                                                  logicalToPhysical()
                                                  requestPaint()
                                              }
                                  
                                              width: parent.width
                                              height: parent.height
                                              anchors.margins: 50
                                              antialiasing: true
                                              renderStrategy: Canvas.Cooperative
                                  
                                              property color linecolor: "#808080"
                                              property color background: "#f5f5f5"
                                  
                                              //            property int yRef: chart.height/2 - chart.xAxisHeight
                                              //            property int xRef: chart.yAxisWidth + 100
                                  
                                              property int yAxisWidth: 80   // x pos of y-axis in pixel
                                              property int xAxisHeight: 40  // y distance of x-axis from bottom in pixel
                                  
                                              property bool fillAreas: false
                                              property int scalingFactor: 30
                                  
                                              function drawAxis(ctx) {
                                                  var yAxis = {
                                                      labels: ["+6 dB", "0 dB", "-6 dB", "-12 dB", "-18 dB"],
                                                      lines: [0.0, 0.22, 0.44, 0.66, 0.88]
                                                  }
                                  
                                                  var xAxis = {
                                                      labels: ["100 mm", "150 mm", "200 mm", "250 mm", "300 mm",
                                                          "350 mm", "400 mm", "450 mm", "500 mm", "550 mm"],
                                                      lines: [0.0, 0.15, 0.25, 0.35, 0.50,
                                                          0.60, 0.70, 0.82, 0.92, 1.00]
                                                  }
                                  
                                                  //                var y0 = 50.0;
                                                  //                var y1 = chart.height - chart.xAxisHeight
                                                  //                var x0 = chart.yAxisWidth
                                                  //                var x1 = chart.width - 100
                                  
                                                  // clear
                                                  ctx.fillStyle = background
                                                  ctx.fillRect(0,0,width,height)
                                  
                                                  // frame
                                                  ctx.strokeStyle = linecolor;
                                                  ctx.fillStyle = "#999999";
                                                  ctx.lineWidth = 1
                                  
                                                  ctx.beginPath();
                                                  ctx.moveTo(x0,y0);
                                  
                                                  ctx.lineTo(x1,y0);
                                                  ctx.lineTo(x1,y1);
                                                  ctx.lineTo(x0,y1);
                                                  ctx.lineTo(x0,y0);
                                                  ctx.stroke()
                                  
                                                  var w
                                                  var yp
                                  
                                                  //drawing the small lines on the X and Y axis
                                                  for (var y = 0; y < yAxis.lines.length; y++)
                                                  {
                                                      ctx.beginPath();
                                                      ctx.strokeStyle = "black"
                                                      yp = (y1 - y0) * yAxis.lines[y] + y0
                                                      ctx.moveTo(x0 - 10, yp);
                                                      ctx.lineTo(x0, yp);
                                                      ctx.stroke();
                                                      ctx.closePath();
                                  
                                                      //                w = ctx.measureText(yAxis.labels[y]).width
                                                      //                ctx.fillText(yAxis.labels[y], x0 - w -5, yp + 5)
                                                  }
                                  
                                                  for (var x = 0; x < xAxis.lines.length; x++)
                                                  {
                                                      ctx.beginPath();
                                                      var xp = (x1 - x0) * xAxis.lines[x] + x0
                                                      ctx.moveTo(xp, y1);
                                                      ctx.lineTo(xp, y1 + 5);
                                                      ctx.stroke();
                                                      ctx.closePath();
                                  
                                                      ctx.fillText(xAxis.labels[x], xp - 20, y1 + 20)
                                                  }
                                                  ctx.beginPath();
                                                  console.log("drawing the graph")
                                                  console.log("chart width"+ chart.width);
                                  
                                                  ctx.moveTo(physicalValue_x[0],physicalValue_z[0]);
                                                  for( var i=1;i< physicalValue_x.length;i++){
                                                      ctx.lineTo(physicalValue_x[i],physicalValue_z[i])
                                                  }
                                                  ctx.lineWidth = 2
                                                  ctx.stroke();
                                                  ctx.closePath();
                                              }
                                              onPaint: {
                                                  var ctx = getContext("2d");
                                                  //                ctx.save();
                                                  drawAxis(ctx)
                                                  //                ctx.restore();
                                              }
                                          }
                                          Rectangle {
                                              id: point1
                                              x: currentPos_x
                                              y: currentPos_z
                                              z:10
                                              radius: 5
                                              width: 60; height: 15
                                              color: "#800096d6"
                                              Text{
                                                  id:currentpoisionText
                                                  anchors.centerIn: parent
                                                  text: showPos_x+","+showPos_z
                                              }
                                          }
                                      }
                                  }
                                  

                                  try to ignore the function inputToGraph and connections because it is from cpp side.

                                  p3c0P Offline
                                  p3c0P Offline
                                  p3c0
                                  Moderators
                                  wrote on last edited by
                                  #16

                                  @vishnu It appears to be the problem with the initialization of properties as well as the intialization of items from where these properties are accessed. It seems that when Canvas is created and its heightChanged signal is invoked the property logicalValue_z is not initialized yet and thus causes that error but very first time only. Later it doesnt seems to give that error. This can be avoided by adding another condition where you can check if that property is initialized just like you checked physicalValue_x

                                  if(physicalValue_x && logicalValue_z){
                                      logicalToPhysical()
                                      requestPaint()
                                  }
                                  

                                  157

                                  vishnuV 1 Reply Last reply
                                  1
                                  • p3c0P p3c0

                                    @vishnu It appears to be the problem with the initialization of properties as well as the intialization of items from where these properties are accessed. It seems that when Canvas is created and its heightChanged signal is invoked the property logicalValue_z is not initialized yet and thus causes that error but very first time only. Later it doesnt seems to give that error. This can be avoided by adding another condition where you can check if that property is initialized just like you checked physicalValue_x

                                    if(physicalValue_x && logicalValue_z){
                                        logicalToPhysical()
                                        requestPaint()
                                    }
                                    
                                    vishnuV Offline
                                    vishnuV Offline
                                    vishnu
                                    wrote on last edited by
                                    #17

                                    @p3c0
                                    perfect. May i know what does this mean exactly? if(physicalValue_x && logicalValue_z) . I am assuming at this point physicalValue_x!=0 and logicalValue_z !=0 .then it enters inside the condition.

                                    p3c0P 1 Reply Last reply
                                    0
                                    • vishnuV vishnu

                                      @p3c0
                                      perfect. May i know what does this mean exactly? if(physicalValue_x && logicalValue_z) . I am assuming at this point physicalValue_x!=0 and logicalValue_z !=0 .then it enters inside the condition.

                                      p3c0P Offline
                                      p3c0P Offline
                                      p3c0
                                      Moderators
                                      wrote on last edited by
                                      #18

                                      @vishnu The control will go ahead if and only if both properties are initialized. Its a normal & operation.

                                      157

                                      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