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. QQuickPaintedItem rotation causing aliasing
Forum Update on Monday, May 27th 2025

QQuickPaintedItem rotation causing aliasing

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
8 Posts 2 Posters 1.3k 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.
  • Z Offline
    Z Offline
    zhannum
    wrote on last edited by zhannum
    #1

    Hi,

    I'm working on implementing a custom round rectangle using QQuickPaintedItem so that I can change each corner radii independently and I'm running into an issue with rotating the object. Antialiasing seems to be working properly when the object is painted, but when I rotate the object via QML, aliasing appears along the diagonal edges of the rectangle. I can "hack" a fix to this by increasing the item's height and width and draw the rectangle inside the bounds of the item, but this solution requires a lot of hacky code.

    No rotation:
    0_1556128698190_3facc8f2-f09e-45d6-8877-0c64b44cf0c1-image.png

    Rotation with jaggies:
    0_1556128722708_7752b931-b8a9-4f07-9cc7-61919f2a64d7-image.png

    Here's my paint method:

        double buffer = 0; //Used to draw inside the item instead of on the edges
    
        if(tilt())
        {
            buffer += 1;
        }
        //start
        path.moveTo(width() - topRightRadius() - buffer, buffer);
    
        //Top horizontal
        path.lineTo(topLeftRadius() + buffer, buffer);
    
        //Top left radius
        path.arcTo(buffer, buffer, topLeftRadius(), topLeftRadius(), 90, 90);
    
        //Left vertical
        path.lineTo(buffer, height() - bottomLeftRadius() + buffer);
    
        //Bottom left radius
        path.arcTo(buffer, height() - bottomLeftRadius() - buffer, bottomLeftRadius(), bottomLeftRadius(), 180, 90);
    
        //Bottom horizontal
        path.lineTo(width() - bottomRightRadius() - buffer, height() - buffer);
    
        //Bottom right radius
        path.arcTo(width() - bottomRightRadius() - buffer, height() - bottomRightRadius() - buffer, bottomRightRadius(), bottomRightRadius(), 270, 90);
    
        //Right vertical
        path.lineTo(width() - buffer, topRightRadius() + buffer);
    
        //Top right radius
        path.arcTo(width() - topRightRadius() - buffer, buffer, topRightRadius(), topRightRadius(), 0, 90);
    
        setAntialiasing(true);
        QBrush brush(QColor("#53b748"));
    
        painter->setBrush(brush);
        painter->setPen(Qt::NoPen);
        painter->setRenderHint(QPainter::Antialiasing, true);
        painter->drawPath(path);
    

    Is there a fix for this? A better way to implement what I want? I'm open to any and all suggestions.

    raven-worxR 1 Reply Last reply
    0
    • Z zhannum

      Hi,

      I'm working on implementing a custom round rectangle using QQuickPaintedItem so that I can change each corner radii independently and I'm running into an issue with rotating the object. Antialiasing seems to be working properly when the object is painted, but when I rotate the object via QML, aliasing appears along the diagonal edges of the rectangle. I can "hack" a fix to this by increasing the item's height and width and draw the rectangle inside the bounds of the item, but this solution requires a lot of hacky code.

      No rotation:
      0_1556128698190_3facc8f2-f09e-45d6-8877-0c64b44cf0c1-image.png

      Rotation with jaggies:
      0_1556128722708_7752b931-b8a9-4f07-9cc7-61919f2a64d7-image.png

      Here's my paint method:

          double buffer = 0; //Used to draw inside the item instead of on the edges
      
          if(tilt())
          {
              buffer += 1;
          }
          //start
          path.moveTo(width() - topRightRadius() - buffer, buffer);
      
          //Top horizontal
          path.lineTo(topLeftRadius() + buffer, buffer);
      
          //Top left radius
          path.arcTo(buffer, buffer, topLeftRadius(), topLeftRadius(), 90, 90);
      
          //Left vertical
          path.lineTo(buffer, height() - bottomLeftRadius() + buffer);
      
          //Bottom left radius
          path.arcTo(buffer, height() - bottomLeftRadius() - buffer, bottomLeftRadius(), bottomLeftRadius(), 180, 90);
      
          //Bottom horizontal
          path.lineTo(width() - bottomRightRadius() - buffer, height() - buffer);
      
          //Bottom right radius
          path.arcTo(width() - bottomRightRadius() - buffer, height() - bottomRightRadius() - buffer, bottomRightRadius(), bottomRightRadius(), 270, 90);
      
          //Right vertical
          path.lineTo(width() - buffer, topRightRadius() + buffer);
      
          //Top right radius
          path.arcTo(width() - topRightRadius() - buffer, buffer, topRightRadius(), topRightRadius(), 0, 90);
      
          setAntialiasing(true);
          QBrush brush(QColor("#53b748"));
      
          painter->setBrush(brush);
          painter->setPen(Qt::NoPen);
          painter->setRenderHint(QPainter::Antialiasing, true);
          painter->drawPath(path);
      

      Is there a fix for this? A better way to implement what I want? I'm open to any and all suggestions.

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

      @zhannum
      how do you rotate via QML? are you sure is in exact 90 degree steps?

      A workaround could be to bind the antialiasing property to rotation % 90.0 !== 0.0

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      Z 1 Reply Last reply
      0
      • raven-worxR raven-worx

        @zhannum
        how do you rotate via QML? are you sure is in exact 90 degree steps?

        A workaround could be to bind the antialiasing property to rotation % 90.0 !== 0.0

        Z Offline
        Z Offline
        zhannum
        wrote on last edited by
        #3

        @raven-worx

        I only want to rotate 5 degrees. I want to rotate when the item is dragged, so I have:

        rotation: Drag.active ? 5 : 0
        
        raven-worxR 1 Reply Last reply
        0
        • Z zhannum

          @raven-worx

          I only want to rotate 5 degrees. I want to rotate when the item is dragged, so I have:

          rotation: Drag.active ? 5 : 0
          
          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @zhannum
          also make sure that you round the x and y coordinates after the drag has finished.
          Ensuring that the pos and size is even on pixels should prevent the need for antialiasing

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • Z Offline
            Z Offline
            zhannum
            wrote on last edited by
            #5

            @raven-worx
            I'm not sure what you mean. Even if I just rotate it in place without dragging it the aliasing still appears:
            0_1556132002084_652b52f8-5f7a-4d80-be4e-aaffdd998863-image.png

            rotation: 5
            
            raven-worxR 2 Replies Last reply
            0
            • Z zhannum

              @raven-worx
              I'm not sure what you mean. Even if I just rotate it in place without dragging it the aliasing still appears:
              0_1556132002084_652b52f8-5f7a-4d80-be4e-aaffdd998863-image.png

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

              @zhannum said in QQuickPaintedItem rotation causing aliasing:

              I'm not sure what you mean.

              i meant when you are finished with dragging, you should ensure that the item's x and y coordinate and its width and height is not any floating value

              Even if I just rotate it in place without dragging it the aliasing still appears

              this doesnt look very antialiased to me?
              your first screenshot does though.

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              Z 1 Reply Last reply
              0
              • raven-worxR raven-worx

                @zhannum said in QQuickPaintedItem rotation causing aliasing:

                I'm not sure what you mean.

                i meant when you are finished with dragging, you should ensure that the item's x and y coordinate and its width and height is not any floating value

                Even if I just rotate it in place without dragging it the aliasing still appears

                this doesnt look very antialiased to me?
                your first screenshot does though.

                Z Offline
                Z Offline
                zhannum
                wrote on last edited by zhannum
                #7

                @raven-worx

                The x and y of the object after a drop event are set in QML, and are always set to integer values.

                this doesnt look very antialiased to me?
                your first screenshot does though.

                I agree. The jagged aliasing is what I'd like to fix. Basically how the diagonal line is made up of small horizontal lines, giving the appearance of steps.
                0_1556136852368_c495ce12-1a2b-4115-aa66-85d5678e9af1-image.png

                With my hacky fix I've implemented, this is what the result looks like, which is what I want:
                0_1556136996928_b9ea979e-d001-4edb-93ab-d259cf8a4e02-image.png

                To better illustrate how I'm "hacking" a solution, i've set the fillColor of the item to white:
                0_1556137075921_13551cd9-3b41-4bfb-9826-fbe72dcf40a0-image.png

                You can see that the edges of the QQuickItem become jagged when rotated.

                1 Reply Last reply
                0
                • Z zhannum

                  @raven-worx
                  I'm not sure what you mean. Even if I just rotate it in place without dragging it the aliasing still appears:
                  0_1556132002084_652b52f8-5f7a-4d80-be4e-aaffdd998863-image.png

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

                  @zhannum said in QQuickPaintedItem rotation causing aliasing:

                  I agree. The jagged aliasing is what I'd like to fix

                  now i finally got you.
                  You may want to read the following. If you use OpenGL?
                  https://doc.qt.io/qt-5/qtquick-visualcanvas-scenegraph-renderer.html#antialiasing

                  so you might want to try msaa. I assume the software renderer's (QPainter) antialiasing method is closer to to this one.

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  1 Reply Last reply
                  0

                  • Login

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