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. Coordinate system issues in QPaint

Coordinate system issues in QPaint

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 2.2k 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.
  • D Offline
    D Offline
    David406
    wrote on last edited by David406
    #1

    Hi all, I'm a Qt beginner and met a problem when reading examples on QPaint. Here's the reimplemented paintEvent() code:

    void painterTime::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing, true);
        QPen pen(Qt::black);
        pen.setWidth(6);
        painter.setPen(pen);
        QRect r = rect().adjusted(10, 10, -10, -10);
        painter.drawRoundedRect(r, 20, 10);
        painter.save();
        r.adjust(20, 20, -20, -20);
        painter.setViewport(r);
        r.moveTo(0, -r.height()/2);
        painter.setWindow(r);
        drawChart(&painter, r);
        painter.restore();
    }
    

    and the drawChart() member function is defined as follows:

    void painterTime::drawChart(QPainter *painter, const QRect &rect)
    {
        painter->setPen(Qt::red);
        painter->drawLine(0, 0, rect.width(), 0);
    }
    

    The resulting paint is:
    alternate text
    Which is not what I'm expecting it to be.

    Since I suppose the origin of painter coordinate system to be the default origin of widget client region, namely the top-left corner of geometry(), the result should be something like this:
    alternate text
    because in drawChart function, a line is drawn without clipping from the origin with a length of the width of the window and viewport, and in my opinion the origion of painter is the same as the device because I have not transformed it. To confirm my guess, I modified the code paint part:

    void painterTime::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing, true);
        QPen pen(Qt::black);
        pen.setWidth(6);
        painter.setPen(pen);
        int w = rect().width();
        int h = rect().height();
        painter.setWindow(0, -h/2, w, h);
        painter.setViewport(w/4, h/4, w/2, h/2);
        painter.drawRect(0, -h/2, w, h);
    }
    

    It draws as expected and confirms my guesss that painter coordinate system is the same as that of the device:
    alternate text
    My logic is deducted as follows:
    alt text
    So I got a contradiction.

    My question is what actually is the coordinate system and origin of QPainter instance? How to explain this contradiction I got? If you have any question about my statement, please leave a comment! Any help will be greatly appreciated!

    FlotisableF 1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by
      #2

      Hi! The image-upload feature on our forum is broken, you might see the picture but other users don't. Please upload your image to a image hoster of your choice (e.g. postimage.org) and embed the pic here with the following markup: ![alternate text](image-url).See also How to insert image on this forum and Hitchhiker's Visual Guide to the Qt Forum.

      1 Reply Last reply
      0
      • D David406

        Hi all, I'm a Qt beginner and met a problem when reading examples on QPaint. Here's the reimplemented paintEvent() code:

        void painterTime::paintEvent(QPaintEvent *)
        {
            QPainter painter(this);
            painter.setRenderHint(QPainter::Antialiasing, true);
            QPen pen(Qt::black);
            pen.setWidth(6);
            painter.setPen(pen);
            QRect r = rect().adjusted(10, 10, -10, -10);
            painter.drawRoundedRect(r, 20, 10);
            painter.save();
            r.adjust(20, 20, -20, -20);
            painter.setViewport(r);
            r.moveTo(0, -r.height()/2);
            painter.setWindow(r);
            drawChart(&painter, r);
            painter.restore();
        }
        

        and the drawChart() member function is defined as follows:

        void painterTime::drawChart(QPainter *painter, const QRect &rect)
        {
            painter->setPen(Qt::red);
            painter->drawLine(0, 0, rect.width(), 0);
        }
        

        The resulting paint is:
        alternate text
        Which is not what I'm expecting it to be.

        Since I suppose the origin of painter coordinate system to be the default origin of widget client region, namely the top-left corner of geometry(), the result should be something like this:
        alternate text
        because in drawChart function, a line is drawn without clipping from the origin with a length of the width of the window and viewport, and in my opinion the origion of painter is the same as the device because I have not transformed it. To confirm my guess, I modified the code paint part:

        void painterTime::paintEvent(QPaintEvent *)
        {
            QPainter painter(this);
            painter.setRenderHint(QPainter::Antialiasing, true);
            QPen pen(Qt::black);
            pen.setWidth(6);
            painter.setPen(pen);
            int w = rect().width();
            int h = rect().height();
            painter.setWindow(0, -h/2, w, h);
            painter.setViewport(w/4, h/4, w/2, h/2);
            painter.drawRect(0, -h/2, w, h);
        }
        

        It draws as expected and confirms my guesss that painter coordinate system is the same as that of the device:
        alternate text
        My logic is deducted as follows:
        alt text
        So I got a contradiction.

        My question is what actually is the coordinate system and origin of QPainter instance? How to explain this contradiction I got? If you have any question about my statement, please leave a comment! Any help will be greatly appreciated!

        FlotisableF Offline
        FlotisableF Offline
        Flotisable
        wrote on last edited by Flotisable
        #3

        @David406
        if you can confirms that the coordinate system is the same as the device from the paintEvent you modified. I think you know that setViewport changes the physical coordinate to QRect(w/4,h/4,w/2,h/2), and setWindow changes the logical coordinate to QRect(0,-h/2,w,h).

        if I understand correctly about painter's window and viewport

        now you draw a rect with logical coordinate QRect(0,-h/2,w,h), it will map to physical coordinate QRect(w/4,h/4,w/2,h/2).

        for the first paintEvent, setViewport changes the physical coordinate to QRect(30,30,rect().width()-60,rect().height()-60)
        and setWindow changes the logical coordinate to QRect(0,-(rect().height()-60)/2,rect().width()-60,rect().height()-60)( x move 30 and y move ( rect().height() - 60 ) / 2 + 30 )

        you draw a line with logical coordinate QLine(0,0,rect().width()-60,0) which will map to physical coordinate
        QLine(30,30+(rect().height()-60)/2,rect().width()-30,30+(rect().height()-60)/2)

        to simplify, you draw a line with logical coordinate in the middle of the painter's window, it will map to the middle of the painter's viewport

        since the viewport does not touch the widget's border, this line will not touch the widget's border

        sample

        1 Reply Last reply
        2
        • D Offline
          D Offline
          David406
          wrote on last edited by David406
          #4

          @Flotisable
          Thanks for your detailed explanation! I found that I made a mistake with the moveTo method. I have updated my question and added a picture deducting my logic for the confirmation code. Could you please take a look at it and suggest if I'm right on the coordinates? By the way, you might need to open this picture in your desktop so as to zoom in.

          FlotisableF 1 Reply Last reply
          0
          • D David406

            @Flotisable
            Thanks for your detailed explanation! I found that I made a mistake with the moveTo method. I have updated my question and added a picture deducting my logic for the confirmation code. Could you please take a look at it and suggest if I'm right on the coordinates? By the way, you might need to open this picture in your desktop so as to zoom in.

            FlotisableF Offline
            FlotisableF Offline
            Flotisable
            wrote on last edited by
            #5

            @David406
            your logic about the confirmation code is the same as mine. maybe it's my bad explanation that you don't get the point.

            so do you understand why the result of paint does not match your expectation?

            to explain more clear, I use picture to explain step by step

            from the start you have a rect of the widget
            rect

            after painter.setViewport( r ), the viewport will be
            rect and view port

            after painter.setWindow( r ), you will have a window
            ( to make the picture more clear, I do not place the window on the right place, but point out it's coordinate )
            rect, viewport and window

            then painter->drawLine( 0, 0, rect.width(), 0 ) will have
            rect, viewport and window with a line

            the line will map to viewport this way
            rect, viewport and window with a line map to viewport

            so you get a line in the middle of the widget
            this is my opinion

            1 Reply Last reply
            2
            • D Offline
              D Offline
              David406
              wrote on last edited by
              #6

              @Flotisable
              Thanks a lot. I get your point and it helped me realize that I made a mistake on the moveTo method. Now everything is clear. BTW, could I ask with what tool do you draw your pictures?

              FlotisableF 1 Reply Last reply
              0
              • D David406

                @Flotisable
                Thanks a lot. I get your point and it helped me realize that I made a mistake on the moveTo method. Now everything is clear. BTW, could I ask with what tool do you draw your pictures?

                FlotisableF Offline
                FlotisableF Offline
                Flotisable
                wrote on last edited by
                #7

                @David406
                I use "libreoffice draw"

                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