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. Mapping scene coordinates and Item coordinates
Forum Update on Monday, May 27th 2025

Mapping scene coordinates and Item coordinates

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 2 Posters 1.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.
  • N Offline
    N Offline
    newToQt26
    wrote on 13 Sept 2020, 09:01 last edited by
    #1

    Hey everyone !

    I do not seem to understand how the coordinate mapping is done. What I want to achieve is restrict my custom QGraphicsRectItem inside sceneRect . I tried doing it with itemChange method . But it doesnot work.

    My sceneRect is set as (-800,-400,1600,800) . So when I move my item around , its coordinates(the value stored in QVariant value parameter of itemChange() method) and scene coordinates does not match at all , and as a result the restricting area is entirely different from the sceneRect area.

    Also when I draw a rectangle in the middle of the scene , then the restricting area is approximately same as the sceneRect area and both the coordinates match too. How can I get this same behaviour with all the other rectangles drawn anywhere else inside scene?

    Can someone help me with whats happening with coordinates?
    Thank You !

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mrjj
      Lifetime Qt Champion
      wrote on 13 Sept 2020, 09:15 last edited by
      #2

      Hi
      Are you saying the example form the docs no longer work and wont keep
      the item inside scene rect ?
      https://doc.qt.io/qt-5/qgraphicsitem.html#itemChange

      N 1 Reply Last reply 13 Sept 2020, 09:37
      0
      • M mrjj
        13 Sept 2020, 09:15

        Hi
        Are you saying the example form the docs no longer work and wont keep
        the item inside scene rect ?
        https://doc.qt.io/qt-5/qgraphicsitem.html#itemChange

        N Offline
        N Offline
        newToQt26
        wrote on 13 Sept 2020, 09:37 last edited by
        #3

        @mrjj Hey !

        Not really..but doesnot work the way its intended to be.

        demo.png demo1.png

        In both the screenshots , the rectangle's restricting area is entirely different. My scene rect is the middle Rectangle with gridlines. I have zoomed out. both the rectangles should have been restricted inside the sceneRect , but thats not the case.
        Is it because I'm setting the rectangle via setRect() method ?

        This is by dragging :

        rectItem->setRect(QRectF(event->scenePos(),QSize(80,50)));
        

        this is using scene Mouse events:

         mRect->setRect(QRectF(startingPoint,event->scenePos()).normalized());
        
        1 Reply Last reply
        0
        • M Offline
          M Offline
          mrjj
          Lifetime Qt Champion
          wrote on 13 Sept 2020, 09:58 last edited by
          #4

          Hi
          but is setRect not in item coordinates ?
          In any case does it move the rectangel or does nothing happen ?

          1 Reply Last reply
          0
          • N Offline
            N Offline
            newToQt26
            wrote on 13 Sept 2020, 10:13 last edited by
            #5

            umm nope ! I am setting it in scene coordinates. selecting tool rectangle then the rectangle gets drawn from the the point where mouse was pressed , which becomes topLeft , and the point where mouse was released becomes bottom right , everything in Scene coordinates and scene Mouse Events.
            But yeah , rectangle moves fine and even its movements get restricted , but just not inside sceneRect.

            However , I made some changes to itemChange() . Somebody suggested to do the following changes :

             if(!sceneRect.contains(pos)){
                           pos.setX(qMin(sceneRect.right()-boundingRect().right(),
                                qMax(pos.x(), sceneRect.left())));
                            pos.setY(qMin(sceneRect.bottom()-boundingRect().bottom(), 
                                qMax(pos.y(), sceneRect.top())));
                            return pos;
            
                    }
            

            And now , the item's movements are getting limited to just right side of sceneRect and bottom of the sceneRect . I cant do the same for left and top . I tried with the same if statement for the new Point

            QPointF newPos = (QPointF(pos.x()+this->rect().width(),
                              pos.y()+this->rect().height()));
            

            But doesnot work.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mrjj
              Lifetime Qt Champion
              wrote on 13 Sept 2020, 10:28 last edited by
              #6

              Hi
              Did you inspect the values when the rect is in left side then ?
              I wonder if its due to left being negative -800, -400

              N 2 Replies Last reply 13 Sept 2020, 10:56
              0
              • M mrjj
                13 Sept 2020, 10:28

                Hi
                Did you inspect the values when the rect is in left side then ?
                I wonder if its due to left being negative -800, -400

                N Offline
                N Offline
                newToQt26
                wrote on 13 Sept 2020, 10:56 last edited by
                #7

                @mrjj Hey !

                Yes , I did inspect the values. but cant make of it ,because it is in item's coordinate system , and I cant compare it with scene coordinates.

                So , according to what I understand , I guess I am making a mistake in itemChange() method. I just adapted it according to documentation and some already existing solutions on internet. I thought by adding the same if condition for newPos point would do the trcik , but I was wrong.

                QVariant ResizableRectangle::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
                {
                
                    if(change==GraphicsItemChange::ItemPositionChange && scene())
                    {
                        qDebug()<<"inside itemChange in if";
                
                       QRectF sceneRect= this->scene()->sceneRect();
                
                        QPointF pos =value.toPointF();;
                        QPointF newPos = (QPointF(pos.x()+this->rect().width(),pos.y()+this->rect().height()));
                        qDebug()<<"pos"<<pos<<"newPos"<<newPos;
                
                        if(!sceneRect.contains(pos)){
                            pos.setX(qMin(sceneRect.right()-boundingRect().right(), qMax(pos.x(), sceneRect.left())));
                            pos.setY(qMin(sceneRect.bottom()-boundingRect().bottom(), qMax(pos.y(), sceneRect.top())));
                            return pos;
                
                        }
                
                        if(!sceneRect.contains(newPos)){
                            newPos.setX(qMin(sceneRect.right()-boundingRect().right(), qMax(newPos.x(), sceneRect.left())));
                            newPos.setY(qMin(sceneRect.bottom()-boundingRect().bottom(), qMax(newPos.y(), sceneRect.top())));
                            return newPos;
                        }
                 }
                   return  QGraphicsItem::itemChange(change,value);
                }
                
                

                So, I think both these if conditions are checking for Right and Bottom only. But again I am clueless how to do the same for top and left .

                1 Reply Last reply
                0
                • M mrjj
                  13 Sept 2020, 10:28

                  Hi
                  Did you inspect the values when the rect is in left side then ?
                  I wonder if its due to left being negative -800, -400

                  N Offline
                  N Offline
                  newToQt26
                  wrote on 13 Sept 2020, 11:07 last edited by
                  #8

                  @mrjj Heyyy !

                  I figured it out ! I just had to make one small change , subtract boundingRect.left() from sceneRect.left() and subtract boundingRect.right() from sceneRect.right() !

                  Here is the code , if anyone needs it.

                  QVariant ResizableRectangle::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
                  {
                  
                      if(change==GraphicsItemChange::ItemPositionChange && scene())
                      {
                          qDebug()<<"inside itemChange in if";
                  
                         QRectF sceneRect= this->scene()->sceneRect();
                  
                          QPointF pos =value.toPointF();;
                          QPointF newPos = QPointF(pos.x()+this->rect().width(),pos.y()+this->rect().height());
                          qDebug()<<"pos"<<pos<<"newPos"<<newPos;
                  
                          if(!sceneRect.contains(pos)){
                              pos.setX(qMin(sceneRect.right()-boundingRect().right(), qMax(pos.x(), sceneRect.left()-boundingRect().left())));
                              pos.setY(qMin(sceneRect.bottom()-boundingRect().bottom(), qMax(pos.y(), sceneRect.top()-boundingRect().top())));
                              return pos;
                  
                          }
                  
                          if(!sceneRect.contains(newPos)){
                              newPos.setX(qMin(sceneRect.right()-boundingRect().right(), qMax(newPos.x(), sceneRect.left()-boundingRect().left())));
                              newPos.setY(qMin(sceneRect.bottom()-boundingRect().bottom(), qMax(newPos.y(), sceneRect.top()-boundingRect().top())));
                              return newPos;
                          }
                   }
                     return  QGraphicsItem::itemChange(change,value);
                  }
                  

                  @mrjj Thank you so much for replying and being so patient and helping me out !

                  M 1 Reply Last reply 13 Sept 2020, 11:12
                  3
                  • N newToQt26
                    13 Sept 2020, 11:07

                    @mrjj Heyyy !

                    I figured it out ! I just had to make one small change , subtract boundingRect.left() from sceneRect.left() and subtract boundingRect.right() from sceneRect.right() !

                    Here is the code , if anyone needs it.

                    QVariant ResizableRectangle::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
                    {
                    
                        if(change==GraphicsItemChange::ItemPositionChange && scene())
                        {
                            qDebug()<<"inside itemChange in if";
                    
                           QRectF sceneRect= this->scene()->sceneRect();
                    
                            QPointF pos =value.toPointF();;
                            QPointF newPos = QPointF(pos.x()+this->rect().width(),pos.y()+this->rect().height());
                            qDebug()<<"pos"<<pos<<"newPos"<<newPos;
                    
                            if(!sceneRect.contains(pos)){
                                pos.setX(qMin(sceneRect.right()-boundingRect().right(), qMax(pos.x(), sceneRect.left()-boundingRect().left())));
                                pos.setY(qMin(sceneRect.bottom()-boundingRect().bottom(), qMax(pos.y(), sceneRect.top()-boundingRect().top())));
                                return pos;
                    
                            }
                    
                            if(!sceneRect.contains(newPos)){
                                newPos.setX(qMin(sceneRect.right()-boundingRect().right(), qMax(newPos.x(), sceneRect.left()-boundingRect().left())));
                                newPos.setY(qMin(sceneRect.bottom()-boundingRect().bottom(), qMax(newPos.y(), sceneRect.top()-boundingRect().top())));
                                return newPos;
                            }
                     }
                       return  QGraphicsItem::itemChange(change,value);
                    }
                    

                    @mrjj Thank you so much for replying and being so patient and helping me out !

                    M Offline
                    M Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on 13 Sept 2020, 11:12 last edited by
                    #9

                    @newToQt26
                    Heey
                    Good work and thank you for sharing :)

                    N 1 Reply Last reply 13 Sept 2020, 11:16
                    0
                    • M mrjj
                      13 Sept 2020, 11:12

                      @newToQt26
                      Heey
                      Good work and thank you for sharing :)

                      N Offline
                      N Offline
                      newToQt26
                      wrote on 13 Sept 2020, 11:16 last edited by
                      #10

                      @mrjj Thank You ! :)

                      1 Reply Last reply
                      0

                      1/10

                      13 Sept 2020, 09:01

                      • Login

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