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. 5 days. I have been trying to center a freakin QGraphicsItem hierarchy. They made this hard.
Forum Updated to NodeBB v4.3 + New Features

5 days. I have been trying to center a freakin QGraphicsItem hierarchy. They made this hard.

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 4 Posters 2.6k 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.
  • enjoysmathE Offline
    enjoysmathE Offline
    enjoysmath
    wrote on last edited by
    #3

    I posted the code. I put it all in one file since I couldn't upload a document zip. Run it, or let me know if it doesn't immediately run. Firs spread the control points in the view. Then try moving the rectangle itself by selecting any part of the rectangle that's not at a control point. The lower / upper / left or right corner gets sucked into the mouse cursor position. I'd like the same to happen but with the center of the boundingRect(), not the corner!

    I have tried at least 100 "permutations" on how it would work from my perfect understanding of the coordinate transformation system. Much of them failed to have an effect on the corner thing. And when they really suck, the whole scene just blows up or the item jets off or starts shaking abrubtly. Why is it so hard to do this? That makes no sense to me.

    https://github.com/enjoysmath
    https://math.stackexchange.com/users/26327/exercisingmathematician

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

      @enjoysmath said in 5 days. I have been trying to center a freakin QGraphicsItem hierarchy. They made this hard.:

      Don't give me this, moveBy, setPos, setTransform crap. It does not work!

      when it doesn't work, you are doing it wrong, obviously.
      Easiest would be when you show some code.

      enjoysmathE Offline
      enjoysmathE Offline
      enjoysmath
      wrote on last edited by
      #4

      @raven-worx

      How is the code above?

      https://github.com/enjoysmath
      https://math.stackexchange.com/users/26327/exercisingmathematician

      raven-worxR 1 Reply Last reply
      0
      • enjoysmathE enjoysmath

        @raven-worx

        How is the code above?

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

        @enjoysmath
        sry i am not very good with Python. Maybe someone else can help here?
        When i spot something i let you know.

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

        enjoysmathE 2 Replies Last reply
        0
        • raven-worxR raven-worx

          @enjoysmath
          sry i am not very good with Python. Maybe someone else can help here?
          When i spot something i let you know.

          enjoysmathE Offline
          enjoysmathE Offline
          enjoysmath
          wrote on last edited by
          #6

          @raven-worx Thanks. Anything you code in C++ I can convert to Python easily. I'm familiar with Python mostly, but have toiled in C++ / QtCreator.

          This problem is not specific to Python, I am 100% confident that you will find the same graphics item "features" in an analogous C++ version.

          https://github.com/enjoysmath
          https://math.stackexchange.com/users/26327/exercisingmathematician

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

            @enjoysmath
            sry i am not very good with Python. Maybe someone else can help here?
            When i spot something i let you know.

            enjoysmathE Offline
            enjoysmathE Offline
            enjoysmath
            wrote on last edited by enjoysmath
            #7

            @raven-worx In other words, given a graphics item hierarchy : A -> B -> C, where -> is "is a parent of", how would you let C move freely (control points), where B's boundingRect() is the minimal bounding rect of all control points C in B, and I want to keep B's boundingRect() appearing centered on A's position?

            Hold on... that just gave me an idea.

            K, stuck in same boat. Here is a Pain3D png of what I want for the control point drag action.
            0_1555715275862_PyQt5cumber_ItemCenteringBug1.png

            By "origin" in the image I mean pos()

            https://github.com/enjoysmath
            https://math.stackexchange.com/users/26327/exercisingmathematician

            KillerSmathK 1 Reply Last reply
            0
            • enjoysmathE enjoysmath

              @raven-worx In other words, given a graphics item hierarchy : A -> B -> C, where -> is "is a parent of", how would you let C move freely (control points), where B's boundingRect() is the minimal bounding rect of all control points C in B, and I want to keep B's boundingRect() appearing centered on A's position?

              Hold on... that just gave me an idea.

              K, stuck in same boat. Here is a Pain3D png of what I want for the control point drag action.
              0_1555715275862_PyQt5cumber_ItemCenteringBug1.png

              By "origin" in the image I mean pos()

              KillerSmathK Offline
              KillerSmathK Offline
              KillerSmath
              wrote on last edited by
              #8

              @enjoysmath

              The (0,0) point inside a child is the same (0,0) point inside your parent.

              Noticed, when you are trying to centralize an object in a graphicsview, you have to translate a half to left and top to keep it on center:
              Rect(-5,-5,10,10) => Centralized Rect with Width and Height = 10 on position (0,0).

              By what i understand, you are trying to resize the parent by child position B -> C. I had a similiar problem in an old project. See an example.

              0_1555716971827_Peek 19-04-2019 19-30.gif

              I am not sure how you can achieve this goal on PyQt but i can give you an example on Cpp.

              .h file

              class MovableCircle : public QGraphicsObject
              {
                  Q_OBJECT
              public:
                  explicit MovableCircle(QGraphicsItem *parent = 0);
              
              private:
                  QRectF boundingRect() const;
                  QPainterPath shape() const;
                  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                  void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
                  void mousePressEvent(QGraphicsSceneMouseEvent *event);
                  void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
                  QPointF _shiftMouseCoords;
              
              signals:
                  void circleMoved();
              };
              
              class BoundedRect : public QGraphicsObject
              {
                  Q_OBJECT
              public:
                  BoundedRect(QGraphicsItem *parent = 0);
                  QRectF boundingRect() const;
              
              private:
                  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                  MovableCircle *_topLeftCircle, *_topRightCircle, *_bottomLeftCircle, *_bottomRightCircle;
                  QSizeF _size;
              };
              

              .cpp file

              #include "moveitem.h"
              
              #include <QtMath>
              
              //////////////////////
              ///  Movable Circle
              //////////////////////
              
              MovableCircle::MovableCircle(QGraphicsItem *parent) :
                  QGraphicsObject(parent)
              {
                  setFlag(ItemClipsToShape, true);
                  setCursor(QCursor(Qt::PointingHandCursor));
              }
              
              QRectF MovableCircle::boundingRect() const
              {
                  qreal adjust = 0.5;
                  return QRectF(-5 - adjust, -5 - adjust,
                                10 + adjust, 10 + adjust);
              }
              
              QPainterPath MovableCircle::shape() const
              {
                  QPainterPath path;
                  qreal adjust = 0.5;
                  path.addEllipse(-5 - adjust, -5 - adjust,
                                  10 + adjust, 10 + adjust);
                  return path;
              }
              
              void MovableCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
              {
                  Q_UNUSED(option);
                  Q_UNUSED(widget);
              
                  painter->setBrush(QBrush(Qt::red));
                  painter->setPen(QPen(Qt::black));
                  painter->drawEllipse(-5, -5, 10, 10);
              }
              
              void MovableCircle::mousePressEvent(QGraphicsSceneMouseEvent *event)
              {
                  _shiftMouseCoords = this->pos() - mapToScene(event->pos());
                  this->setCursor(QCursor(Qt::ClosedHandCursor));
              }
              
              void MovableCircle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
              {
                  setPos(mapToScene(event->pos() + _shiftMouseCoords));
                  emit circleMoved();
              }
              
              void MovableCircle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
              {
                  Q_UNUSED(event);
                  this->setCursor(QCursor(Qt::PointingHandCursor));
              }
              
              //////////////////////
              ///  Bounded Class
              //////////////////////
              
              BoundedRect::BoundedRect(QGraphicsItem *parent)
                  : QGraphicsObject(parent), _size(180, 180) // Using the Construtor to setup te variable
              {
                  setFlag(QGraphicsItem::ItemIsMovable, true);
              
                  // Top Left
                  _topLeftCircle = new MovableCircle(this);
                  _topLeftCircle->setPos(-_size.width()/2, -_size.width()/2);
                  // Top Right
                  _topRightCircle = new MovableCircle(this);
                  _topRightCircle->setPos(_size.width()/2, -_size.width()/2);
                  // Bottom Left
                  _bottomLeftCircle = new MovableCircle(this);
                  _bottomLeftCircle->setPos(-_size.width()/2, _size.width()/2);
                  // Bottom Right
                  _bottomRightCircle = new MovableCircle(this);
                  _bottomRightCircle->setPos(_size.width()/2, _size.width()/2);
              
                  // Signals
                  // If a delimiter point has been moved, so force the item to redraw
                  
                  connect(_topLeftCircle, &MovableCircle::circleMoved, this, [this](){
                      _bottomLeftCircle->setPos(_topLeftCircle->pos().x(), _bottomLeftCircle->pos().y());
                      _topRightCircle->setPos(_topRightCircle->pos().x(), _topLeftCircle->pos().y());
                      update(); // force to Repaint
                  });
              
                  connect(_topRightCircle, &MovableCircle::circleMoved, this, [this](){
                      _topLeftCircle->setPos(_topLeftCircle->pos().x(), _topRightCircle->pos().y());
                      _bottomRightCircle->setPos(_topRightCircle->pos().x(), _bottomRightCircle->pos().y());
                      update(); // force to Repaint
                  });
              
                  connect(_bottomLeftCircle, &MovableCircle::circleMoved, this, [this](){
                      _topLeftCircle->setPos(_bottomLeftCircle->pos().x(), _topLeftCircle->pos().y());
                      _bottomRightCircle->setPos(_bottomRightCircle->pos().x(), _bottomLeftCircle->pos().y());
                      update(); // force to Repaint
                  });
              
                  connect(_bottomRightCircle, &MovableCircle::circleMoved, this, [this](){
                      _bottomLeftCircle->setPos(_bottomLeftCircle->pos().x(), _bottomRightCircle->pos().y());
                      _topRightCircle->setPos(_bottomRightCircle->pos().x(), _topRightCircle->pos().y());
                      update(); // force to Repaint
                  });
              }
              
              QRectF BoundedRect::boundingRect() const
              {
                  // Calculate the Bouding Rect by 4 Limit Points
                  
                  qreal distX = sqrt(pow(_topLeftCircle->x() - _topRightCircle->x(),2) +
                                     pow(_topLeftCircle->y() - _topRightCircle->y(),2)); // eucledian distance
              
                  qreal distY = sqrt(pow(_topLeftCircle->x() - _bottomLeftCircle->x(),2) +
                                     pow(_topLeftCircle->y() - _bottomLeftCircle->y(),2)); // eucledian distance
              
                  return QRectF(qMin(_topLeftCircle->pos().x(), _topRightCircle->pos().x()) ,
                                qMin(_topLeftCircle->pos().y(), _bottomLeftCircle->pos().y()),
                                distX, distY);
              }
              
              void BoundedRect::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
              {
                  Q_UNUSED(option);
                  Q_UNUSED(widget);
                  
                  painter->setBrush(QBrush(Qt::blue));
                  painter->setPen(QPen(Qt::black));
                  painter->drawRect(boundingRect()); // draw by boundingRect
              }
              
              

              @Computer Science Student - Brazil
              Web Developer and Researcher
              “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

              enjoysmathE S 3 Replies Last reply
              4
              • KillerSmathK KillerSmath

                @enjoysmath

                The (0,0) point inside a child is the same (0,0) point inside your parent.

                Noticed, when you are trying to centralize an object in a graphicsview, you have to translate a half to left and top to keep it on center:
                Rect(-5,-5,10,10) => Centralized Rect with Width and Height = 10 on position (0,0).

                By what i understand, you are trying to resize the parent by child position B -> C. I had a similiar problem in an old project. See an example.

                0_1555716971827_Peek 19-04-2019 19-30.gif

                I am not sure how you can achieve this goal on PyQt but i can give you an example on Cpp.

                .h file

                class MovableCircle : public QGraphicsObject
                {
                    Q_OBJECT
                public:
                    explicit MovableCircle(QGraphicsItem *parent = 0);
                
                private:
                    QRectF boundingRect() const;
                    QPainterPath shape() const;
                    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
                    void mousePressEvent(QGraphicsSceneMouseEvent *event);
                    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
                    QPointF _shiftMouseCoords;
                
                signals:
                    void circleMoved();
                };
                
                class BoundedRect : public QGraphicsObject
                {
                    Q_OBJECT
                public:
                    BoundedRect(QGraphicsItem *parent = 0);
                    QRectF boundingRect() const;
                
                private:
                    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                    MovableCircle *_topLeftCircle, *_topRightCircle, *_bottomLeftCircle, *_bottomRightCircle;
                    QSizeF _size;
                };
                

                .cpp file

                #include "moveitem.h"
                
                #include <QtMath>
                
                //////////////////////
                ///  Movable Circle
                //////////////////////
                
                MovableCircle::MovableCircle(QGraphicsItem *parent) :
                    QGraphicsObject(parent)
                {
                    setFlag(ItemClipsToShape, true);
                    setCursor(QCursor(Qt::PointingHandCursor));
                }
                
                QRectF MovableCircle::boundingRect() const
                {
                    qreal adjust = 0.5;
                    return QRectF(-5 - adjust, -5 - adjust,
                                  10 + adjust, 10 + adjust);
                }
                
                QPainterPath MovableCircle::shape() const
                {
                    QPainterPath path;
                    qreal adjust = 0.5;
                    path.addEllipse(-5 - adjust, -5 - adjust,
                                    10 + adjust, 10 + adjust);
                    return path;
                }
                
                void MovableCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
                {
                    Q_UNUSED(option);
                    Q_UNUSED(widget);
                
                    painter->setBrush(QBrush(Qt::red));
                    painter->setPen(QPen(Qt::black));
                    painter->drawEllipse(-5, -5, 10, 10);
                }
                
                void MovableCircle::mousePressEvent(QGraphicsSceneMouseEvent *event)
                {
                    _shiftMouseCoords = this->pos() - mapToScene(event->pos());
                    this->setCursor(QCursor(Qt::ClosedHandCursor));
                }
                
                void MovableCircle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
                {
                    setPos(mapToScene(event->pos() + _shiftMouseCoords));
                    emit circleMoved();
                }
                
                void MovableCircle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
                {
                    Q_UNUSED(event);
                    this->setCursor(QCursor(Qt::PointingHandCursor));
                }
                
                //////////////////////
                ///  Bounded Class
                //////////////////////
                
                BoundedRect::BoundedRect(QGraphicsItem *parent)
                    : QGraphicsObject(parent), _size(180, 180) // Using the Construtor to setup te variable
                {
                    setFlag(QGraphicsItem::ItemIsMovable, true);
                
                    // Top Left
                    _topLeftCircle = new MovableCircle(this);
                    _topLeftCircle->setPos(-_size.width()/2, -_size.width()/2);
                    // Top Right
                    _topRightCircle = new MovableCircle(this);
                    _topRightCircle->setPos(_size.width()/2, -_size.width()/2);
                    // Bottom Left
                    _bottomLeftCircle = new MovableCircle(this);
                    _bottomLeftCircle->setPos(-_size.width()/2, _size.width()/2);
                    // Bottom Right
                    _bottomRightCircle = new MovableCircle(this);
                    _bottomRightCircle->setPos(_size.width()/2, _size.width()/2);
                
                    // Signals
                    // If a delimiter point has been moved, so force the item to redraw
                    
                    connect(_topLeftCircle, &MovableCircle::circleMoved, this, [this](){
                        _bottomLeftCircle->setPos(_topLeftCircle->pos().x(), _bottomLeftCircle->pos().y());
                        _topRightCircle->setPos(_topRightCircle->pos().x(), _topLeftCircle->pos().y());
                        update(); // force to Repaint
                    });
                
                    connect(_topRightCircle, &MovableCircle::circleMoved, this, [this](){
                        _topLeftCircle->setPos(_topLeftCircle->pos().x(), _topRightCircle->pos().y());
                        _bottomRightCircle->setPos(_topRightCircle->pos().x(), _bottomRightCircle->pos().y());
                        update(); // force to Repaint
                    });
                
                    connect(_bottomLeftCircle, &MovableCircle::circleMoved, this, [this](){
                        _topLeftCircle->setPos(_bottomLeftCircle->pos().x(), _topLeftCircle->pos().y());
                        _bottomRightCircle->setPos(_bottomRightCircle->pos().x(), _bottomLeftCircle->pos().y());
                        update(); // force to Repaint
                    });
                
                    connect(_bottomRightCircle, &MovableCircle::circleMoved, this, [this](){
                        _bottomLeftCircle->setPos(_bottomLeftCircle->pos().x(), _bottomRightCircle->pos().y());
                        _topRightCircle->setPos(_bottomRightCircle->pos().x(), _topRightCircle->pos().y());
                        update(); // force to Repaint
                    });
                }
                
                QRectF BoundedRect::boundingRect() const
                {
                    // Calculate the Bouding Rect by 4 Limit Points
                    
                    qreal distX = sqrt(pow(_topLeftCircle->x() - _topRightCircle->x(),2) +
                                       pow(_topLeftCircle->y() - _topRightCircle->y(),2)); // eucledian distance
                
                    qreal distY = sqrt(pow(_topLeftCircle->x() - _bottomLeftCircle->x(),2) +
                                       pow(_topLeftCircle->y() - _bottomLeftCircle->y(),2)); // eucledian distance
                
                    return QRectF(qMin(_topLeftCircle->pos().x(), _topRightCircle->pos().x()) ,
                                  qMin(_topLeftCircle->pos().y(), _bottomLeftCircle->pos().y()),
                                  distX, distY);
                }
                
                void BoundedRect::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
                {
                    Q_UNUSED(option);
                    Q_UNUSED(widget);
                    
                    painter->setBrush(QBrush(Qt::blue));
                    painter->setPen(QPen(Qt::black));
                    painter->drawRect(boundingRect()); // draw by boundingRect
                }
                
                
                enjoysmathE Offline
                enjoysmathE Offline
                enjoysmath
                wrote on last edited by
                #9

                @KillerSmath

                Thank you, I can definitely look through and understand your code.

                https://github.com/enjoysmath
                https://math.stackexchange.com/users/26327/exercisingmathematician

                1 Reply Last reply
                0
                • KillerSmathK KillerSmath

                  @enjoysmath

                  The (0,0) point inside a child is the same (0,0) point inside your parent.

                  Noticed, when you are trying to centralize an object in a graphicsview, you have to translate a half to left and top to keep it on center:
                  Rect(-5,-5,10,10) => Centralized Rect with Width and Height = 10 on position (0,0).

                  By what i understand, you are trying to resize the parent by child position B -> C. I had a similiar problem in an old project. See an example.

                  0_1555716971827_Peek 19-04-2019 19-30.gif

                  I am not sure how you can achieve this goal on PyQt but i can give you an example on Cpp.

                  .h file

                  class MovableCircle : public QGraphicsObject
                  {
                      Q_OBJECT
                  public:
                      explicit MovableCircle(QGraphicsItem *parent = 0);
                  
                  private:
                      QRectF boundingRect() const;
                      QPainterPath shape() const;
                      void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                      void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
                      void mousePressEvent(QGraphicsSceneMouseEvent *event);
                      void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
                      QPointF _shiftMouseCoords;
                  
                  signals:
                      void circleMoved();
                  };
                  
                  class BoundedRect : public QGraphicsObject
                  {
                      Q_OBJECT
                  public:
                      BoundedRect(QGraphicsItem *parent = 0);
                      QRectF boundingRect() const;
                  
                  private:
                      void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                      MovableCircle *_topLeftCircle, *_topRightCircle, *_bottomLeftCircle, *_bottomRightCircle;
                      QSizeF _size;
                  };
                  

                  .cpp file

                  #include "moveitem.h"
                  
                  #include <QtMath>
                  
                  //////////////////////
                  ///  Movable Circle
                  //////////////////////
                  
                  MovableCircle::MovableCircle(QGraphicsItem *parent) :
                      QGraphicsObject(parent)
                  {
                      setFlag(ItemClipsToShape, true);
                      setCursor(QCursor(Qt::PointingHandCursor));
                  }
                  
                  QRectF MovableCircle::boundingRect() const
                  {
                      qreal adjust = 0.5;
                      return QRectF(-5 - adjust, -5 - adjust,
                                    10 + adjust, 10 + adjust);
                  }
                  
                  QPainterPath MovableCircle::shape() const
                  {
                      QPainterPath path;
                      qreal adjust = 0.5;
                      path.addEllipse(-5 - adjust, -5 - adjust,
                                      10 + adjust, 10 + adjust);
                      return path;
                  }
                  
                  void MovableCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
                  {
                      Q_UNUSED(option);
                      Q_UNUSED(widget);
                  
                      painter->setBrush(QBrush(Qt::red));
                      painter->setPen(QPen(Qt::black));
                      painter->drawEllipse(-5, -5, 10, 10);
                  }
                  
                  void MovableCircle::mousePressEvent(QGraphicsSceneMouseEvent *event)
                  {
                      _shiftMouseCoords = this->pos() - mapToScene(event->pos());
                      this->setCursor(QCursor(Qt::ClosedHandCursor));
                  }
                  
                  void MovableCircle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
                  {
                      setPos(mapToScene(event->pos() + _shiftMouseCoords));
                      emit circleMoved();
                  }
                  
                  void MovableCircle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
                  {
                      Q_UNUSED(event);
                      this->setCursor(QCursor(Qt::PointingHandCursor));
                  }
                  
                  //////////////////////
                  ///  Bounded Class
                  //////////////////////
                  
                  BoundedRect::BoundedRect(QGraphicsItem *parent)
                      : QGraphicsObject(parent), _size(180, 180) // Using the Construtor to setup te variable
                  {
                      setFlag(QGraphicsItem::ItemIsMovable, true);
                  
                      // Top Left
                      _topLeftCircle = new MovableCircle(this);
                      _topLeftCircle->setPos(-_size.width()/2, -_size.width()/2);
                      // Top Right
                      _topRightCircle = new MovableCircle(this);
                      _topRightCircle->setPos(_size.width()/2, -_size.width()/2);
                      // Bottom Left
                      _bottomLeftCircle = new MovableCircle(this);
                      _bottomLeftCircle->setPos(-_size.width()/2, _size.width()/2);
                      // Bottom Right
                      _bottomRightCircle = new MovableCircle(this);
                      _bottomRightCircle->setPos(_size.width()/2, _size.width()/2);
                  
                      // Signals
                      // If a delimiter point has been moved, so force the item to redraw
                      
                      connect(_topLeftCircle, &MovableCircle::circleMoved, this, [this](){
                          _bottomLeftCircle->setPos(_topLeftCircle->pos().x(), _bottomLeftCircle->pos().y());
                          _topRightCircle->setPos(_topRightCircle->pos().x(), _topLeftCircle->pos().y());
                          update(); // force to Repaint
                      });
                  
                      connect(_topRightCircle, &MovableCircle::circleMoved, this, [this](){
                          _topLeftCircle->setPos(_topLeftCircle->pos().x(), _topRightCircle->pos().y());
                          _bottomRightCircle->setPos(_topRightCircle->pos().x(), _bottomRightCircle->pos().y());
                          update(); // force to Repaint
                      });
                  
                      connect(_bottomLeftCircle, &MovableCircle::circleMoved, this, [this](){
                          _topLeftCircle->setPos(_bottomLeftCircle->pos().x(), _topLeftCircle->pos().y());
                          _bottomRightCircle->setPos(_bottomRightCircle->pos().x(), _bottomLeftCircle->pos().y());
                          update(); // force to Repaint
                      });
                  
                      connect(_bottomRightCircle, &MovableCircle::circleMoved, this, [this](){
                          _bottomLeftCircle->setPos(_bottomLeftCircle->pos().x(), _bottomRightCircle->pos().y());
                          _topRightCircle->setPos(_bottomRightCircle->pos().x(), _topRightCircle->pos().y());
                          update(); // force to Repaint
                      });
                  }
                  
                  QRectF BoundedRect::boundingRect() const
                  {
                      // Calculate the Bouding Rect by 4 Limit Points
                      
                      qreal distX = sqrt(pow(_topLeftCircle->x() - _topRightCircle->x(),2) +
                                         pow(_topLeftCircle->y() - _topRightCircle->y(),2)); // eucledian distance
                  
                      qreal distY = sqrt(pow(_topLeftCircle->x() - _bottomLeftCircle->x(),2) +
                                         pow(_topLeftCircle->y() - _bottomLeftCircle->y(),2)); // eucledian distance
                  
                      return QRectF(qMin(_topLeftCircle->pos().x(), _topRightCircle->pos().x()) ,
                                    qMin(_topLeftCircle->pos().y(), _bottomLeftCircle->pos().y()),
                                    distX, distY);
                  }
                  
                  void BoundedRect::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
                  {
                      Q_UNUSED(option);
                      Q_UNUSED(widget);
                      
                      painter->setBrush(QBrush(Qt::blue));
                      painter->setPen(QPen(Qt::black));
                      painter->drawRect(boundingRect()); // draw by boundingRect
                  }
                  
                  
                  enjoysmathE Offline
                  enjoysmathE Offline
                  enjoysmath
                  wrote on last edited by
                  #10

                  @KillerSmath

                  Sadly, this doesn't resolve my issues. I'm still troubleshooting it.

                  Remember, I want pressing on the items to center the item on the mouse cursor.

                  https://github.com/enjoysmath
                  https://math.stackexchange.com/users/26327/exercisingmathematician

                  KillerSmathK 1 Reply Last reply
                  0
                  • enjoysmathE enjoysmath

                    @KillerSmath

                    Sadly, this doesn't resolve my issues. I'm still troubleshooting it.

                    Remember, I want pressing on the items to center the item on the mouse cursor.

                    KillerSmathK Offline
                    KillerSmathK Offline
                    KillerSmath
                    wrote on last edited by
                    #11

                    @enjoysmath
                    We need more information...

                    1. Your image is very polluated and confused
                    2. Try to describe what you pretent to achieve with this manipulation and maybe it can be clearier to understand.

                    @Computer Science Student - Brazil
                    Web Developer and Researcher
                    “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

                    1 Reply Last reply
                    0
                    • KillerSmathK KillerSmath

                      @enjoysmath

                      The (0,0) point inside a child is the same (0,0) point inside your parent.

                      Noticed, when you are trying to centralize an object in a graphicsview, you have to translate a half to left and top to keep it on center:
                      Rect(-5,-5,10,10) => Centralized Rect with Width and Height = 10 on position (0,0).

                      By what i understand, you are trying to resize the parent by child position B -> C. I had a similiar problem in an old project. See an example.

                      0_1555716971827_Peek 19-04-2019 19-30.gif

                      I am not sure how you can achieve this goal on PyQt but i can give you an example on Cpp.

                      .h file

                      class MovableCircle : public QGraphicsObject
                      {
                          Q_OBJECT
                      public:
                          explicit MovableCircle(QGraphicsItem *parent = 0);
                      
                      private:
                          QRectF boundingRect() const;
                          QPainterPath shape() const;
                          void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                          void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
                          void mousePressEvent(QGraphicsSceneMouseEvent *event);
                          void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
                          QPointF _shiftMouseCoords;
                      
                      signals:
                          void circleMoved();
                      };
                      
                      class BoundedRect : public QGraphicsObject
                      {
                          Q_OBJECT
                      public:
                          BoundedRect(QGraphicsItem *parent = 0);
                          QRectF boundingRect() const;
                      
                      private:
                          void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                          MovableCircle *_topLeftCircle, *_topRightCircle, *_bottomLeftCircle, *_bottomRightCircle;
                          QSizeF _size;
                      };
                      

                      .cpp file

                      #include "moveitem.h"
                      
                      #include <QtMath>
                      
                      //////////////////////
                      ///  Movable Circle
                      //////////////////////
                      
                      MovableCircle::MovableCircle(QGraphicsItem *parent) :
                          QGraphicsObject(parent)
                      {
                          setFlag(ItemClipsToShape, true);
                          setCursor(QCursor(Qt::PointingHandCursor));
                      }
                      
                      QRectF MovableCircle::boundingRect() const
                      {
                          qreal adjust = 0.5;
                          return QRectF(-5 - adjust, -5 - adjust,
                                        10 + adjust, 10 + adjust);
                      }
                      
                      QPainterPath MovableCircle::shape() const
                      {
                          QPainterPath path;
                          qreal adjust = 0.5;
                          path.addEllipse(-5 - adjust, -5 - adjust,
                                          10 + adjust, 10 + adjust);
                          return path;
                      }
                      
                      void MovableCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
                      {
                          Q_UNUSED(option);
                          Q_UNUSED(widget);
                      
                          painter->setBrush(QBrush(Qt::red));
                          painter->setPen(QPen(Qt::black));
                          painter->drawEllipse(-5, -5, 10, 10);
                      }
                      
                      void MovableCircle::mousePressEvent(QGraphicsSceneMouseEvent *event)
                      {
                          _shiftMouseCoords = this->pos() - mapToScene(event->pos());
                          this->setCursor(QCursor(Qt::ClosedHandCursor));
                      }
                      
                      void MovableCircle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
                      {
                          setPos(mapToScene(event->pos() + _shiftMouseCoords));
                          emit circleMoved();
                      }
                      
                      void MovableCircle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
                      {
                          Q_UNUSED(event);
                          this->setCursor(QCursor(Qt::PointingHandCursor));
                      }
                      
                      //////////////////////
                      ///  Bounded Class
                      //////////////////////
                      
                      BoundedRect::BoundedRect(QGraphicsItem *parent)
                          : QGraphicsObject(parent), _size(180, 180) // Using the Construtor to setup te variable
                      {
                          setFlag(QGraphicsItem::ItemIsMovable, true);
                      
                          // Top Left
                          _topLeftCircle = new MovableCircle(this);
                          _topLeftCircle->setPos(-_size.width()/2, -_size.width()/2);
                          // Top Right
                          _topRightCircle = new MovableCircle(this);
                          _topRightCircle->setPos(_size.width()/2, -_size.width()/2);
                          // Bottom Left
                          _bottomLeftCircle = new MovableCircle(this);
                          _bottomLeftCircle->setPos(-_size.width()/2, _size.width()/2);
                          // Bottom Right
                          _bottomRightCircle = new MovableCircle(this);
                          _bottomRightCircle->setPos(_size.width()/2, _size.width()/2);
                      
                          // Signals
                          // If a delimiter point has been moved, so force the item to redraw
                          
                          connect(_topLeftCircle, &MovableCircle::circleMoved, this, [this](){
                              _bottomLeftCircle->setPos(_topLeftCircle->pos().x(), _bottomLeftCircle->pos().y());
                              _topRightCircle->setPos(_topRightCircle->pos().x(), _topLeftCircle->pos().y());
                              update(); // force to Repaint
                          });
                      
                          connect(_topRightCircle, &MovableCircle::circleMoved, this, [this](){
                              _topLeftCircle->setPos(_topLeftCircle->pos().x(), _topRightCircle->pos().y());
                              _bottomRightCircle->setPos(_topRightCircle->pos().x(), _bottomRightCircle->pos().y());
                              update(); // force to Repaint
                          });
                      
                          connect(_bottomLeftCircle, &MovableCircle::circleMoved, this, [this](){
                              _topLeftCircle->setPos(_bottomLeftCircle->pos().x(), _topLeftCircle->pos().y());
                              _bottomRightCircle->setPos(_bottomRightCircle->pos().x(), _bottomLeftCircle->pos().y());
                              update(); // force to Repaint
                          });
                      
                          connect(_bottomRightCircle, &MovableCircle::circleMoved, this, [this](){
                              _bottomLeftCircle->setPos(_bottomLeftCircle->pos().x(), _bottomRightCircle->pos().y());
                              _topRightCircle->setPos(_bottomRightCircle->pos().x(), _topRightCircle->pos().y());
                              update(); // force to Repaint
                          });
                      }
                      
                      QRectF BoundedRect::boundingRect() const
                      {
                          // Calculate the Bouding Rect by 4 Limit Points
                          
                          qreal distX = sqrt(pow(_topLeftCircle->x() - _topRightCircle->x(),2) +
                                             pow(_topLeftCircle->y() - _topRightCircle->y(),2)); // eucledian distance
                      
                          qreal distY = sqrt(pow(_topLeftCircle->x() - _bottomLeftCircle->x(),2) +
                                             pow(_topLeftCircle->y() - _bottomLeftCircle->y(),2)); // eucledian distance
                      
                          return QRectF(qMin(_topLeftCircle->pos().x(), _topRightCircle->pos().x()) ,
                                        qMin(_topLeftCircle->pos().y(), _bottomLeftCircle->pos().y()),
                                        distX, distY);
                      }
                      
                      void BoundedRect::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
                      {
                          Q_UNUSED(option);
                          Q_UNUSED(widget);
                          
                          painter->setBrush(QBrush(Qt::blue));
                          painter->setPen(QPen(Qt::black));
                          painter->drawRect(boundingRect()); // draw by boundingRect
                      }
                      
                      
                      S Offline
                      S Offline
                      StudentScripter
                      wrote on last edited by
                      #12

                      @KillerSmath Your example is great, exactly what i was looking for, but nevertheless, i noticed that this system breaks when there is rotation involved. I'm pretty new with all this but may you or anyone else can hint me the way on how get it working with rotation? Thanks alot beforehand. :)

                      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