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. I may be met a rendering problem when I used the Canvas of QML to draw a line

I may be met a rendering problem when I used the Canvas of QML to draw a line

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
qmljscriptqtquickqt6
8 Posts 4 Posters 1.7k 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.
  • T Offline
    T Offline
    Tiny Leaf
    wrote on 7 Nov 2023, 08:33 last edited by
    #1

    I encapsulate a control with canvas. When it get a coordinate array, it can draw the trajectory the array discribed.But during development process,I met a problem and I will simplify the problem in this question. First ,let us read the code following.

    Canvas {
        anchors.centerIn: parent
    
        width: 500
        height: 500
    
        Rectangle {
            anchors.fill: parent
            border.width: 1
            color: "transparent"
        }
    
        onPaint: {
            var ctx = getContext('2d')
            ctx.lineWidth = 2
            ctx.strokeStyle = "yellow"
    
            ctx.beginPath()
    
            ctx.moveTo(100, 100)
            ctx.lineTo(300, 100)
    
            ctx.moveTo(100, 150)
            ctx.lineTo(300, 150)
            ctx.lineTo(100, 150)
            ctx.lineTo(300, 150)
    
            ctx.closePath()
            ctx.stroke()
        }
    }
    

    The output is:
    output.png
    When I draw along with a line or an arc back and forth, the both ends of the line will automatically draw an extra section. But the data is large,I can avoid this phenomenon. So do you konw the solution?Could some one teach me?It is important for me,thanks a lot!

    M 1 Reply Last reply 10 Nov 2023, 17:24
    0
    • T Tiny Leaf
      7 Nov 2023, 08:33

      I encapsulate a control with canvas. When it get a coordinate array, it can draw the trajectory the array discribed.But during development process,I met a problem and I will simplify the problem in this question. First ,let us read the code following.

      Canvas {
          anchors.centerIn: parent
      
          width: 500
          height: 500
      
          Rectangle {
              anchors.fill: parent
              border.width: 1
              color: "transparent"
          }
      
          onPaint: {
              var ctx = getContext('2d')
              ctx.lineWidth = 2
              ctx.strokeStyle = "yellow"
      
              ctx.beginPath()
      
              ctx.moveTo(100, 100)
              ctx.lineTo(300, 100)
      
              ctx.moveTo(100, 150)
              ctx.lineTo(300, 150)
              ctx.lineTo(100, 150)
              ctx.lineTo(300, 150)
      
              ctx.closePath()
              ctx.stroke()
          }
      }
      

      The output is:
      output.png
      When I draw along with a line or an arc back and forth, the both ends of the line will automatically draw an extra section. But the data is large,I can avoid this phenomenon. So do you konw the solution?Could some one teach me?It is important for me,thanks a lot!

      M Offline
      M Offline
      Markkyboy
      wrote on 10 Nov 2023, 17:24 last edited by
      #2

      @Tiny-Leaf - you haven't simplified anything, your question is difficult to understand, at least to me and possibly 26 other people.

      I pasted your code and got the same result you show in your image. What were you expecting?, please give some indication of what you expect to see, even if you mock it up using Paint or GIMP, give us a clue.

      Don't just sit there standing around, pick up a shovel and sweep up!

      I live by the sea, not in it.

      T 1 Reply Last reply 16 Nov 2023, 06:54
      0
      • M Markkyboy
        10 Nov 2023, 17:24

        @Tiny-Leaf - you haven't simplified anything, your question is difficult to understand, at least to me and possibly 26 other people.

        I pasted your code and got the same result you show in your image. What were you expecting?, please give some indication of what you expect to see, even if you mock it up using Paint or GIMP, give us a clue.

        T Offline
        T Offline
        Tiny Leaf
        wrote on 16 Nov 2023, 06:54 last edited by
        #3

        @Markkyboy I don't think you're paying attention to the coordinates. These two lines should be drawn to the same length. Instead of the second one being longer than the first one. This is also the question I wish to raise. Both of these lines should be 200 pixels long. This is precisely the question I wish to raise. The second line appears to have rendered an extra section at both ends, causing it to be longer than the actual 200 pixels. And what causes this problem is that when I draw the second line, I draw again from the end to the beginning, and from the beginning back to the end.
        I wonder if this is a bug of Canvas.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jeremy_k
          wrote on 16 Nov 2023, 08:09 last edited by
          #4

          With Qt 6.5.1, It's the closePath() call that results in extra length. Overdrawing the line doesn't make a difference. Adding a call to closePath() after the line from (100,100) to (300,100) results in both lines being the same length, somewhere over 200 pixels. Removing the call to closePath() fixes the issue, or at least hides it.

          It looks like a bug to me, but I'm not that familiar with the canvas element.

          Asking a question about code? http://eel.is/iso-c++/testcase/

          T 1 Reply Last reply 17 Nov 2023, 07:12
          0
          • J jeremy_k
            16 Nov 2023, 08:09

            With Qt 6.5.1, It's the closePath() call that results in extra length. Overdrawing the line doesn't make a difference. Adding a call to closePath() after the line from (100,100) to (300,100) results in both lines being the same length, somewhere over 200 pixels. Removing the call to closePath() fixes the issue, or at least hides it.

            It looks like a bug to me, but I'm not that familiar with the canvas element.

            T Offline
            T Offline
            Tiny Leaf
            wrote on 17 Nov 2023, 07:12 last edited by
            #5

            @jeremy_k Actually, this proble has no relative with the 'closePath' called.
            'clothPath()' will create a closed figure,for example:

             onPaint: {
                        var ctx = getContext('2d')
                        ctx.lineWidth = 2
                        ctx.strokeStyle = "yellow"
            
                        ctx.moveTo(100, 150)
                        ctx.lineTo(300, 150)
                        ctx.lineTo(200, 200)
            
                        ctx.stroke()
                    }
            

            For the above code, if I don't call the closePath(),we will get the following result:1700203229832.jpg

            But , if i call the closePath(),we will get a triangle because 'clothPath()' will automatically connect the end point and start point:

            onPaint: {
                        var ctx = getContext('2d')
                        ctx.lineWidth = 2
                        ctx.strokeStyle = "yellow"
            
                        ctx.beginPath()
            
                        ctx.moveTo(100, 150)
                        ctx.lineTo(300, 150)
                        ctx.lineTo(200, 200)
            
                        ctx.closePath()
                        ctx.stroke()
                    }
            

            1700203486479.jpg

            Then return to my problem, speak accurately,I met a rendering problem. The main cause of this problem is that when I draw multiple line segments, rendering problems occur if two line segments overlap more than one another.
            Image_1700203958579.jpg

            So, if I want to draw a trejectory like this:
            Image_1700204291196.jpg
            (Make an explanation:Since my canvas needs to draw different tracks when it is used, I use loops when I draw to ensure that I can draw various tracks when I pass parameters externally)
            When I want to draw the above trajectory, I have to draw from A to B ,then draw from B to A ,then draw from A to C ,then draw from C to A and so on. So there will be a a lot of overlap during drawing.
            Finally, I got the result just like following:
            Image_1700204750137.jpg

            In short, when I draw with canvas, if I encounter overlapping parts, I will produce unexpected rendering results.I think this is bug of canvas.

            I don't konw if I made a clear statement. If any questions, welcom to leave a comment.

            J 1 Reply Last reply 17 Nov 2023, 07:33
            0
            • T Tiny Leaf
              17 Nov 2023, 07:12

              @jeremy_k Actually, this proble has no relative with the 'closePath' called.
              'clothPath()' will create a closed figure,for example:

               onPaint: {
                          var ctx = getContext('2d')
                          ctx.lineWidth = 2
                          ctx.strokeStyle = "yellow"
              
                          ctx.moveTo(100, 150)
                          ctx.lineTo(300, 150)
                          ctx.lineTo(200, 200)
              
                          ctx.stroke()
                      }
              

              For the above code, if I don't call the closePath(),we will get the following result:1700203229832.jpg

              But , if i call the closePath(),we will get a triangle because 'clothPath()' will automatically connect the end point and start point:

              onPaint: {
                          var ctx = getContext('2d')
                          ctx.lineWidth = 2
                          ctx.strokeStyle = "yellow"
              
                          ctx.beginPath()
              
                          ctx.moveTo(100, 150)
                          ctx.lineTo(300, 150)
                          ctx.lineTo(200, 200)
              
                          ctx.closePath()
                          ctx.stroke()
                      }
              

              1700203486479.jpg

              Then return to my problem, speak accurately,I met a rendering problem. The main cause of this problem is that when I draw multiple line segments, rendering problems occur if two line segments overlap more than one another.
              Image_1700203958579.jpg

              So, if I want to draw a trejectory like this:
              Image_1700204291196.jpg
              (Make an explanation:Since my canvas needs to draw different tracks when it is used, I use loops when I draw to ensure that I can draw various tracks when I pass parameters externally)
              When I want to draw the above trajectory, I have to draw from A to B ,then draw from B to A ,then draw from A to C ,then draw from C to A and so on. So there will be a a lot of overlap during drawing.
              Finally, I got the result just like following:
              Image_1700204750137.jpg

              In short, when I draw with canvas, if I encounter overlapping parts, I will produce unexpected rendering results.I think this is bug of canvas.

              I don't konw if I made a clear statement. If any questions, welcom to leave a comment.

              J Offline
              J Offline
              jeremy_k
              wrote on 17 Nov 2023, 07:33 last edited by
              #6

              @Tiny-Leaf said in I may be met a rendering problem when I used the Canvas of QML to draw a line:

              @jeremy_k Actually, this proble has no relative with the 'closePath' called.

              For the code initially proposed, removing closePath() changed the output to 2 parallel horizontal lines, 200 pixels long. If you redefine the problem, don't be surprised that answers don't apply.

              Asking a question about code? http://eel.is/iso-c++/testcase/

              T 1 Reply Last reply 17 Nov 2023, 08:18
              0
              • J jeremy_k
                17 Nov 2023, 07:33

                @Tiny-Leaf said in I may be met a rendering problem when I used the Canvas of QML to draw a line:

                @jeremy_k Actually, this proble has no relative with the 'closePath' called.

                For the code initially proposed, removing closePath() changed the output to 2 parallel horizontal lines, 200 pixels long. If you redefine the problem, don't be surprised that answers don't apply.

                T Offline
                T Offline
                Tiny Leaf
                wrote on 17 Nov 2023, 08:18 last edited by
                #7

                @jeremy_k Did you read the question carefully? Please answer the question after the actual code, don't waste other people's time, I am correcting your answer. The problem I raised was the rendering problem, and you were talking about closePath

                J 1 Reply Last reply 17 Nov 2023, 15:27
                0
                • T Tiny Leaf
                  17 Nov 2023, 08:18

                  @jeremy_k Did you read the question carefully? Please answer the question after the actual code, don't waste other people's time, I am correcting your answer. The problem I raised was the rendering problem, and you were talking about closePath

                  J Offline
                  J Offline
                  JoeCFD
                  wrote on 17 Nov 2023, 15:27 last edited by JoeCFD
                  #8

                  @Tiny-Leaf
                  Try the following code. The length of three segments should be same.

                  drawLine(ctx, 50, 50, 150, 50);
                  drawLine(ctx, 150, 50, 50, 50);
                  drawLine(ctx, 150, 100, 50, 100);
                  
                  function drawLine(ctx, x1, y1, x2, y2) 
                  {
                          ctx.beginPath()
                          ctx.moveTo(x1, y1)
                          ctx.lineTo(x2, y2)
                          ctx.stroke()
                   }
                  

                  BTW: you may somehow avoid to draw a line twice if possible. It is not efficient.

                  1 Reply Last reply
                  0

                  8/8

                  17 Nov 2023, 15:27

                  • Login

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