Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Discrepancy between drawRect and drawLine
Forum Updated to NodeBB v4.3 + New Features

Discrepancy between drawRect and drawLine

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 2 Posters 1.0k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Adam Crowe
    wrote on last edited by
    #1

    Hello,

    I am seeing a little discrepancy between drawing the same QRectF with drawRect and drawing the individual sides using four drawLine's.

    Take this QRectF for example:

    QRectF rect(44.81574989,0 45.01417423x18.2834643)
    

    Drawing it with:

    painter->fillRect(rect, QBrush(colorBackground));
    

    or with:

    painter->drawRect(rect);
    

    Gives different results to this:

    painter->drawLine(rect.topLeft().x(), rect.topLeft().y(), rect.topRight().x(), rect.topRight().y());
    painter->drawLine(rect.topRight().x(), rect.topRight().y(), rect.bottomRight().x(), rect.bottomRight().y());
    painter->drawLine(rect.bottomRight().x(), rect.bottomRight().y(), rect.bottomLeft().x(), rect.bottomLeft().y());
    painter->drawLine(rect.bottomLeft().x(), rect.bottomLeft().y(), rect.topLeft().x(), rect.topLeft().y());
    

    Here's the result:

    alt text

    There should not be any white space inside that square, nor should it overflow on the right. Can someone advise please?

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      I think you are seeing the results of:

      A filled rectangle has a size of rectangle.size(). A stroked rectangle has a size of rectangle.size() plus the pen width.

      https://doc.qt.io/qt-5/qpainter.html#drawRect

      In addition, it might be the result of the overloads you have used: you are drawing lines using integer coordinates, but you draw the rectangle using qreal coordinates. There may be differences in rounding and in effect it has on antialiasing.

      (Z(:^

      A 1 Reply Last reply
      3
      • sierdzioS sierdzio

        I think you are seeing the results of:

        A filled rectangle has a size of rectangle.size(). A stroked rectangle has a size of rectangle.size() plus the pen width.

        https://doc.qt.io/qt-5/qpainter.html#drawRect

        In addition, it might be the result of the overloads you have used: you are drawing lines using integer coordinates, but you draw the rectangle using qreal coordinates. There may be differences in rounding and in effect it has on antialiasing.

        A Offline
        A Offline
        Adam Crowe
        wrote on last edited by
        #3

        @sierdzio Thank you for this!

        I double checked, the .x() and .y() functions do return a qreal. The error would have been significantly larger in my coordinate system if these were int.

        Both drawRect and fillRect draw over the same area which doesn't match the drawLine area.

        If this really was the effect of the extra QPen border around the rectangle, it would have shown up in the Y axis as well. Besides, I did make sure the pen width was set to zero and that's not it.

        Adam

        sierdzioS 1 Reply Last reply
        0
        • A Adam Crowe

          @sierdzio Thank you for this!

          I double checked, the .x() and .y() functions do return a qreal. The error would have been significantly larger in my coordinate system if these were int.

          Both drawRect and fillRect draw over the same area which doesn't match the drawLine area.

          If this really was the effect of the extra QPen border around the rectangle, it would have shown up in the Y axis as well. Besides, I did make sure the pen width was set to zero and that's not it.

          Adam

          sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          @Adam-Crowe said in Discrepancy between drawRect and drawLine:

          @sierdzio Thank you for this!

          I double checked, the .x() and .y() functions do return a qreal. The error would have been significantly larger in my coordinate system if these were int.

          You've double-checked the wrong end ;-) It's the drawLine() which takes ints, conversion is implicit.

          Both drawRect and fillRect draw over the same area which doesn't match the drawLine area.

          If this really was the effect of the extra QPen border around the rectangle, it would have shown up in the Y axis as well. Besides, I did make sure the pen width was set to zero and that's not it.

          Good point. Additionally, see this: https://doc.qt.io/qt-5/qrectf.html#rendering and https://doc.qt.io/qt-5/qpen.html#setWidth

          A line width of zero indicates a cosmetic pen. This means that the pen width is always drawn one pixel wide, [...]

          I still think it does not explain why x() has a shift while y() does not, but maybe it will point you in the right direction.

          (Z(:^

          A 1 Reply Last reply
          2
          • sierdzioS sierdzio

            @Adam-Crowe said in Discrepancy between drawRect and drawLine:

            @sierdzio Thank you for this!

            I double checked, the .x() and .y() functions do return a qreal. The error would have been significantly larger in my coordinate system if these were int.

            You've double-checked the wrong end ;-) It's the drawLine() which takes ints, conversion is implicit.

            Both drawRect and fillRect draw over the same area which doesn't match the drawLine area.

            If this really was the effect of the extra QPen border around the rectangle, it would have shown up in the Y axis as well. Besides, I did make sure the pen width was set to zero and that's not it.

            Good point. Additionally, see this: https://doc.qt.io/qt-5/qrectf.html#rendering and https://doc.qt.io/qt-5/qpen.html#setWidth

            A line width of zero indicates a cosmetic pen. This means that the pen width is always drawn one pixel wide, [...]

            I still think it does not explain why x() has a shift while y() does not, but maybe it will point you in the right direction.

            A Offline
            A Offline
            Adam Crowe
            wrote on last edited by
            #5

            @sierdzio Shocking 😳

            So there's really no way to fill a rectangle without a 1 pixel overflow on the right hand side? My coordinate system represents real world millimetres and gets scaled up on the screen based on the screen's DPI. Accuracy is absolutely paramount. On Windows using .Net, this stuff is trivial because GDI+ does all the conversions for you, but it's been a hell of a challenge with Qt's QPainter to achieve this.

            Do you think QPainter::drawLines(const QVector<QLineF> &lines) would round to an int also?

            Adam

            sierdzioS 1 Reply Last reply
            0
            • A Adam Crowe

              @sierdzio Shocking 😳

              So there's really no way to fill a rectangle without a 1 pixel overflow on the right hand side? My coordinate system represents real world millimetres and gets scaled up on the screen based on the screen's DPI. Accuracy is absolutely paramount. On Windows using .Net, this stuff is trivial because GDI+ does all the conversions for you, but it's been a hell of a challenge with Qt's QPainter to achieve this.

              Do you think QPainter::drawLines(const QVector<QLineF> &lines) would round to an int also?

              Adam

              sierdzioS Offline
              sierdzioS Offline
              sierdzio
              Moderators
              wrote on last edited by
              #6

              @Adam-Crowe said in Discrepancy between drawRect and drawLine:

              So there's really no way to fill a rectangle without a 1 pixel overflow on the right hand side?

              Use fillRect(), it won't have any border and thus should not be shifted. I hope ;-)

              (Z(:^

              A 1 Reply Last reply
              2
              • sierdzioS sierdzio

                @Adam-Crowe said in Discrepancy between drawRect and drawLine:

                So there's really no way to fill a rectangle without a 1 pixel overflow on the right hand side?

                Use fillRect(), it won't have any border and thus should not be shifted. I hope ;-)

                A Offline
                A Offline
                Adam Crowe
                wrote on last edited by
                #7

                @sierdzio YOU WERE SO RIGHT! It was the drawLine that was wrong and not the drawRect or fillRect.

                Once I definite a QLineF line(…) for that line and did a drawLine(line) everything fell right into place!

                Incredible. Thank you so much!!!

                Adam

                1 Reply Last reply
                0
                • sierdzioS Offline
                  sierdzioS Offline
                  sierdzio
                  Moderators
                  wrote on last edited by
                  #8

                  Oh wow, it was just a guess :D OK, I'm glad this is solved. Happy coding!

                  (Z(:^

                  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