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 Updated to NodeBB v4.3 + New Features

Mapping scene coordinates and Item coordinates

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 2 Posters 1.5k 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.
  • N Offline
    N Offline
    newToQt26
    wrote on 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
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on 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
      0
      • mrjjM mrjj

        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 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
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on 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 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
            • mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on 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
              0
              • mrjjM mrjj

                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 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
                • mrjjM mrjj

                  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 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 !

                  mrjjM 1 Reply Last reply
                  3
                  • N newToQt26

                    @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 !

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

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

                    N 1 Reply Last reply
                    0
                    • mrjjM mrjj

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

                      N Offline
                      N Offline
                      newToQt26
                      wrote on last edited by
                      #10

                      @mrjj Thank You ! :)

                      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