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. Flipping QGraphicsRectItem on mouse move?
QtWS25 Last Chance

Flipping QGraphicsRectItem on mouse move?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt c++qgraphicsitem
3 Posts 1 Posters 355 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.
  • S Online
    S Online
    StudentScripter
    wrote on 13 Apr 2024, 18:38 last edited by StudentScripter
    #1

    Hello,
    So i created a qgraphicsrectitem which i painting handles on. When i drag the bottom handle above the top handle i want the image to flip. My logic for the handles is this but problem is the rect gets moved slightly up and down in position when doing the "flip".
    4e9f6ba3-834e-4730-966b-184199e68b2c-image.png
    075ea2d2-050c-40f9-9024-7b28374eae42-image.png
    As you can see it moves slightly on resize, but i couldn't find how to fix that. Any help is appreciated. Thanks in advance. :)

    
    void HandleItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
    
    
    
    
    
        ResizableHandleRect *rectItem = dynamic_cast<ResizableHandleRect *>(parentItem());
    
        if (!rectItem) {
            return; // Wenn das Parent-Item kein ResizableHandleRect ist, beende die Funktion
        }
    
    
    
        QRectF boundingFrameRect = rectItem->selectorFrameBounds();
    
    
        QPointF topLeft = mapToScene(boundingFrameRect.topLeft());
        QPointF bottomRight = mapToScene(boundingFrameRect.bottomRight());
        QRectF SceneBoundingFrameRect(topLeft, bottomRight);
    
        qDebug() << "HandlePosition: " << handlePosition;
    
    
    
    
        switch (handlePosition) {
        case TopLeft:
    
            break;
    
        case TopCenter:
            SceneBoundingFrameRect.setTop(event->scenePos().y());
    
            if(SceneBoundingFrameRect.bottom() < SceneBoundingFrameRect.top()){
                qDebug() << "TEST";
                handlePosition = BottomCenter;
            }
    
            break;
    
        case TopRight:
    
            break;
    
        case RightCenter:
    
            break;
    
        case BottomRight:
    
            break;
    
        case BottomCenter:
            SceneBoundingFrameRect.setBottom(event->scenePos().y());
            OriginBottomCenter = SceneBoundingFrameRect.bottom();
            if(SceneBoundingFrameRect.bottom() < SceneBoundingFrameRect.top()){
                qDebug() << "TEST";
                handlePosition = TopCenter;
            }
    
    
    
            break;
    
        case BottomLeft:
    
            break;
    
        case LeftCenter:
    
            break;
    
        default:
            break;
        }
    
    
    
        QPointF topLeft2 = mapFromScene(SceneBoundingFrameRect.topLeft());
        QPointF bottomRight2 = mapFromScene(SceneBoundingFrameRect.bottomRight());
        QRectF NEWBoundingFrameRect2(topLeft2, bottomRight2);
    
    
    
        rectItem->setSelectorFrameBounds(NEWBoundingFrameRect2);
        
        
    

    This is the main item.cpp:

    ResizablePixmapItem::ResizablePixmapItem(QPixmap pixmap) :
        mPixmap(pixmap)//, ImageFilePath(path)
    {
        setOwnerItem(this);
        
        
    
    }
    
    
    
    
    int ResizablePixmapItem::type() const
    {
    
        return Type;
        
    }
    
    
    
    QRectF ResizablePixmapItem::selectorFrameBounds() const
    {
        
        return  rect();
    }
    
    
    void ResizablePixmapItem::setSelectorFrameBounds(QRectF boundsRect)
    {
    
        prepareGeometryChange();
         
        setRect(boundsRect);
    
        update();
    
    
    }
    
    QRectF ResizablePixmapItem::boundingRect() const
    {
        return selectorFrameBounds();
    }
    
    
    
    
    
    void ResizablePixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        Q_UNUSED(option);
        Q_UNUSED(widget);
        painter->save();
    
        //Malt eine Linie um das Rechteck
        painter->setBrush(brush());
        painter->drawRect(rect());
    
        // Rahmen um das Rechteck malen
        painter->setPen(Qt::NoPen); // Keinen Rahmen um das Rechteck
        painter->setBrush(Qt::green); // Grüne Füllfarbe für den oberen Rahmen
        QRectF topRect = QRectF(boundingRect().topLeft(), QPointF(boundingRect().bottomRight().x(), boundingRect().topLeft().y() + 1));
        painter->drawRect(topRect);
    
        painter->setBrush(Qt::blue); // Blaue Füllfarbe für den unteren Rahmen
        QRectF bottomRect = QRectF(QPointF(boundingRect().topLeft().x(), boundingRect().bottomRight().y() - 1), boundingRect().bottomRight());
        painter->drawRect(bottomRect);
    
        
        
        // Definieren Sie die Größe und Position Ihres Frames im Spritesheet
        QRect SpriteAnimationRect(0, 0, FrameWidth, FrameHeight);
    
        if(boundingRect().height() < 5 && boundingRect().height() > -5){
            // Flip the pixmap vertically
            painter->drawPixmap(boundingRect(),QPixmap(),SpriteAnimationRect);
    
        }else if(boundingRect().height() >=5 || boundingRect().height() <= -5){
    
            painter->drawPixmap(boundingRect(),mPixmap,SpriteAnimationRect);
        }
    
        
    
    
    
    
        
        
    
    
        drawHandlesIfNecessary();
    
        
    
        painter->restore();
    }
    
    

    And this is how i draw the handles:

    
    
    ResizableHandleRect::ResizableHandleRect()
    {
        
    
    }
    
    ResizableHandleRect::~ResizableHandleRect()
    {
    
    }
    
    
    
    
    
    
    
    void ResizableHandleRect::drawHandles()
    {
        //qDebug() << "ResizableHandleRect DrawHandles triggered!";
    
        // Erstellen und Hinzufügen der Handles zur Szene
    
    
        //Populate handles in list
        if(handleList.count() == 0){
            handleList.append(new HandleItem(HandleItem::TopLeft));
            handleList.append(new HandleItem(HandleItem::TopCenter));
            handleList.append(new HandleItem(HandleItem::TopRight));
            handleList.append(new HandleItem(HandleItem::RightCenter));
            handleList.append(new HandleItem(HandleItem::BottomRight));
            handleList.append(new HandleItem(HandleItem::BottomCenter));
            handleList.append(new HandleItem(HandleItem::BottomLeft));
            handleList.append(new HandleItem(HandleItem::LeftCenter));
    
        }
    
        //Set up pen
        QPen mPen;
        mPen.setWidth(2);
        mPen.setColor(Qt::black);
    
        if(ownerItem->boundingRect().height() > 0){
        for (int i = 0; i < handleList.size(); ++i) {
            HandleItem* handle = handleList.at(i);
            QRectF handleRect;
            switch (i) {
            case 0: // Top Left
                handleRect = QRectF(selectorFrameBounds().topLeft() + QPointF(-8.0, -8.0), QSize(8, 8));
                handle->setCursor(Qt::SizeFDiagCursor);
                break;
            case 1: // Top Center
                handleRect = QRectF(selectorFrameBounds().left() + selectorFrameBounds().width() / 2.0 - 4.0, selectorFrameBounds().top() - 8.0, 8, 8);
                handle->setCursor(Qt::SizeVerCursor);
                break;
            case 2: // Top Right
                handleRect = QRectF(selectorFrameBounds().topRight() + QPointF(0, -8.0), QSize(8, 8));
                handle->setCursor(Qt::SizeBDiagCursor);
                break;
            case 3: // Right Center
                handleRect = QRectF(selectorFrameBounds().right() - 0.0, selectorFrameBounds().top() + selectorFrameBounds().height() / 2.0 - 4.0, 8, 8);
                handle->setCursor(Qt::SizeHorCursor);
                break;
            case 4: // Bottom Right
                handleRect = QRectF(selectorFrameBounds().bottomRight(), QSize(8, 8));
                handle->setCursor(Qt::SizeFDiagCursor);
                break;
            case 5: // Bottom Center
                handleRect = QRectF(selectorFrameBounds().left() + selectorFrameBounds().width() / 2.0 - 4.0, selectorFrameBounds().bottom() - 0.0, 8, 8);
                handle->setCursor(Qt::SizeVerCursor);
                break;
            case 6: // Bottom Left
                handleRect = QRectF(selectorFrameBounds().bottomLeft() + QPointF(-8, 0), QSize(8, 8));
                handle->setCursor(Qt::SizeBDiagCursor);
                break;
            case 7: // Left Center
                handleRect = QRectF(selectorFrameBounds().left() - 8.0, selectorFrameBounds().top() + selectorFrameBounds().height() / 2.0 - 4.0, 8, 8);
                handle->setCursor(Qt::SizeHorCursor);
                break;
            default:
                break;
            }
    
              //qDebug() << "ResRectSelBounds:" << selectorFrameBounds().bottom() << selectorFrameBounds().top();
    
            handle->setPen(mPen);
            handle->setRect(handleRect);
            handle->setParentItem(ownerItem);
    
        }
    
        }
    
    
        handlesAddedToScene = true;
    
    
    }
    
    
    
    
    
    QGraphicsItem *ResizableHandleRect::getOwnerItem() const
    {
        return ownerItem;
    }
    
    
    
    
    void ResizableHandleRect::setOwnerItem(QGraphicsItem *value)
    {
        ownerItem = value;
        
    
    }
    
    
    
    
    void ResizableHandleRect::drawHandlesIfNecessary()
    {
        //qDebug() << "DrawHandles" << ShouldDrawHandles << ownerItem->isSelected();
        if(!ownerItem){
            qWarning() << "ResizableHandleRect : No ownerItem set. Not drawing any\
                          handle. Please call setOwnerItem on your ResizableHandleRect subclass";
                          return;
        }
    
    
    
        if(ownerItem->isSelected()){
    
            drawHandles();
    
            handlesAddedToScene = true;
    
            
            
        }else if(!ownerItem->isSelected()){
    
            //Remove the handles
            foreach (HandleItem * handleItem, handleList) {
                ownerItem->scene()->removeItem(handleItem);
    
            }
    
            qDeleteAll(handleList);
            handleList.clear();
            handlesAddedToScene = false;
        }
    
    }
    
    

    If you need more information let me know. I've been trying various things the whole day but couldn't find a solution. Before i used local event->pos() coordinates, same problem. Also the image sometimes glitches out and i don't get why.

    1 Reply Last reply
    0
    • S Online
      S Online
      StudentScripter
      wrote on 14 Apr 2024, 08:31 last edited by
      #2

      I tried to debug further but some things i get are just strange. I can't figure out why this happens:

      ORIG TOP LEFT 0 ORIG BOTTOM RIGHT QPointF(450,292)
      ORIG TOP LEFT 0 ORIG BOTTOM RIGHT QPointF(450,292)
      ORIG TOP LEFT 0 ORIG BOTTOM RIGHT QPointF(450,250)
      ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
      ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
      ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
      ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
      ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
      

      Here is the code i get the debbug from:

      #include "handleitem.h"
      #include "resizablehandlerect.h"
      #include <QGraphicsSceneMouseEvent>
      #include <QDebug>
      #include "resizablepixmapitem.h"
      
      HandleItem::HandleItem(Position position) :
          handlePosition(position)
      {
          setFlag(QGraphicsItem::ItemIsMovable);
      
      
      
      }
      
      
      
      void HandleItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
      {
          ResizableHandleRect *rectItem = dynamic_cast<ResizableHandleRect *>(parentItem());
      
          if (!rectItem) {
              return; // Wenn das Parent-Item kein ResizableHandleRect ist, beende die Funktion
          }
      
      
      
      
          QRectF boundingFrameRect = rectItem->selectorFrameBounds();
      
      
      
          OriginTopLeft = mapToScene(boundingFrameRect.topLeft());
      
          OriginBottomRight = mapToScene(boundingFrameRect.bottomRight());
      
          QRectF SceneBoundingFrameRect(OriginTopLeft, OriginBottomRight);
          qDebug() << "ORIG TOP LEFT" << OriginLeftCenter << "ORIG BOTTOM RIGHT" << OriginBottomRight;
          OriginBottomCenter = SceneBoundingFrameRect.bottom();
          OriginTopCenter = SceneBoundingFrameRect.top();
      
          BottomCenterWasDragged = false;
          TopCenterWasDragged = false;
      }
      
      
      
      
      
      
      void HandleItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
      {
      
      
      
      
      
          ResizableHandleRect *rectItem = dynamic_cast<ResizableHandleRect *>(parentItem());
      
          if (!rectItem) {
              return; // Wenn das Parent-Item kein ResizableHandleRect ist, beende die Funktion
          }
      
      
      
          QRectF boundingFrameRect = rectItem->selectorFrameBounds();
      
      
          QPointF topLeft = mapToScene(boundingFrameRect.topLeft());
          QPointF bottomRight = mapToScene(boundingFrameRect.bottomRight());
          QRectF SceneBoundingFrameRect(topLeft, bottomRight);
      
          //qDebug() << "HandlePosition: " << handlePosition;
      
      
      
      
          switch (handlePosition) {
          case TopLeft:
      
              break;
      
          case TopCenter:
              SceneBoundingFrameRect.setTop(event->scenePos().y());
      
              if(SceneBoundingFrameRect.bottom() < SceneBoundingFrameRect.top() && BottomCenterWasDragged == false){
                  qDebug() << "-- (2)SWITCH Top to Bottom";
                  handlePosition = BottomCenter;
                  TopCenterWasDragged = true;
              }
      
              break;
      
          case TopRight:
      
              break;
      
          case RightCenter:
      
              break;
      
          case BottomRight:
      
              break;
      
          case BottomCenter:
              SceneBoundingFrameRect.setBottom(event->scenePos().y());
              if(SceneBoundingFrameRect.bottom() < SceneBoundingFrameRect.top() && TopCenterWasDragged == false){
                  qDebug() << "(1)SWITCH Bottom to Top--";
                  handlePosition = TopCenter;
                  BottomCenterWasDragged = true;
              }
      
      
      
              break;
      
          case BottomLeft:
      
              break;
      
          case LeftCenter:
      
              break;
      
          default:
              break;
          }
      
      
      
          if(SceneBoundingFrameRect.topLeft() != OriginTopLeft && BottomCenterWasDragged == true){
              SceneBoundingFrameRect.setTopLeft(OriginTopLeft);
              BottomCenterWasDragged = false;
              qDebug() << "(1*)Correct Top, Bottom was Dragged!" << SceneBoundingFrameRect.topLeft();
          }
      
          if(SceneBoundingFrameRect.bottomRight() != OriginBottomRight && TopCenterWasDragged == true){
              SceneBoundingFrameRect.setBottomRight(OriginBottomRight);
              TopCenterWasDragged = false;
              qDebug() << "(2*)Correct Bottom, Top was Dragged!" << SceneBoundingFrameRect.bottomRight();
          }
      
      
      
          QPointF topLeft2 = mapFromScene(SceneBoundingFrameRect.topLeft());
          QPointF bottomRight2 = mapFromScene(SceneBoundingFrameRect.bottomRight());
          QRectF NEWBoundingFrameRect2(topLeft2, bottomRight2);
      
      
      
          rectItem->setSelectorFrameBounds(NEWBoundingFrameRect2);
      
      S 1 Reply Last reply 14 Apr 2024, 13:41
      0
      • S StudentScripter
        14 Apr 2024, 08:31

        I tried to debug further but some things i get are just strange. I can't figure out why this happens:

        ORIG TOP LEFT 0 ORIG BOTTOM RIGHT QPointF(450,292)
        ORIG TOP LEFT 0 ORIG BOTTOM RIGHT QPointF(450,292)
        ORIG TOP LEFT 0 ORIG BOTTOM RIGHT QPointF(450,250)
        ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
        ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
        ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
        ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
        ORIG TOP LEFT nan ORIG BOTTOM RIGHT QPointF(450,250)
        

        Here is the code i get the debbug from:

        #include "handleitem.h"
        #include "resizablehandlerect.h"
        #include <QGraphicsSceneMouseEvent>
        #include <QDebug>
        #include "resizablepixmapitem.h"
        
        HandleItem::HandleItem(Position position) :
            handlePosition(position)
        {
            setFlag(QGraphicsItem::ItemIsMovable);
        
        
        
        }
        
        
        
        void HandleItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
        {
            ResizableHandleRect *rectItem = dynamic_cast<ResizableHandleRect *>(parentItem());
        
            if (!rectItem) {
                return; // Wenn das Parent-Item kein ResizableHandleRect ist, beende die Funktion
            }
        
        
        
        
            QRectF boundingFrameRect = rectItem->selectorFrameBounds();
        
        
        
            OriginTopLeft = mapToScene(boundingFrameRect.topLeft());
        
            OriginBottomRight = mapToScene(boundingFrameRect.bottomRight());
        
            QRectF SceneBoundingFrameRect(OriginTopLeft, OriginBottomRight);
            qDebug() << "ORIG TOP LEFT" << OriginLeftCenter << "ORIG BOTTOM RIGHT" << OriginBottomRight;
            OriginBottomCenter = SceneBoundingFrameRect.bottom();
            OriginTopCenter = SceneBoundingFrameRect.top();
        
            BottomCenterWasDragged = false;
            TopCenterWasDragged = false;
        }
        
        
        
        
        
        
        void HandleItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
        {
        
        
        
        
        
            ResizableHandleRect *rectItem = dynamic_cast<ResizableHandleRect *>(parentItem());
        
            if (!rectItem) {
                return; // Wenn das Parent-Item kein ResizableHandleRect ist, beende die Funktion
            }
        
        
        
            QRectF boundingFrameRect = rectItem->selectorFrameBounds();
        
        
            QPointF topLeft = mapToScene(boundingFrameRect.topLeft());
            QPointF bottomRight = mapToScene(boundingFrameRect.bottomRight());
            QRectF SceneBoundingFrameRect(topLeft, bottomRight);
        
            //qDebug() << "HandlePosition: " << handlePosition;
        
        
        
        
            switch (handlePosition) {
            case TopLeft:
        
                break;
        
            case TopCenter:
                SceneBoundingFrameRect.setTop(event->scenePos().y());
        
                if(SceneBoundingFrameRect.bottom() < SceneBoundingFrameRect.top() && BottomCenterWasDragged == false){
                    qDebug() << "-- (2)SWITCH Top to Bottom";
                    handlePosition = BottomCenter;
                    TopCenterWasDragged = true;
                }
        
                break;
        
            case TopRight:
        
                break;
        
            case RightCenter:
        
                break;
        
            case BottomRight:
        
                break;
        
            case BottomCenter:
                SceneBoundingFrameRect.setBottom(event->scenePos().y());
                if(SceneBoundingFrameRect.bottom() < SceneBoundingFrameRect.top() && TopCenterWasDragged == false){
                    qDebug() << "(1)SWITCH Bottom to Top--";
                    handlePosition = TopCenter;
                    BottomCenterWasDragged = true;
                }
        
        
        
                break;
        
            case BottomLeft:
        
                break;
        
            case LeftCenter:
        
                break;
        
            default:
                break;
            }
        
        
        
            if(SceneBoundingFrameRect.topLeft() != OriginTopLeft && BottomCenterWasDragged == true){
                SceneBoundingFrameRect.setTopLeft(OriginTopLeft);
                BottomCenterWasDragged = false;
                qDebug() << "(1*)Correct Top, Bottom was Dragged!" << SceneBoundingFrameRect.topLeft();
            }
        
            if(SceneBoundingFrameRect.bottomRight() != OriginBottomRight && TopCenterWasDragged == true){
                SceneBoundingFrameRect.setBottomRight(OriginBottomRight);
                TopCenterWasDragged = false;
                qDebug() << "(2*)Correct Bottom, Top was Dragged!" << SceneBoundingFrameRect.bottomRight();
            }
        
        
        
            QPointF topLeft2 = mapFromScene(SceneBoundingFrameRect.topLeft());
            QPointF bottomRight2 = mapFromScene(SceneBoundingFrameRect.bottomRight());
            QRectF NEWBoundingFrameRect2(topLeft2, bottomRight2);
        
        
        
            rectItem->setSelectorFrameBounds(NEWBoundingFrameRect2);
        
        S Online
        S Online
        StudentScripter
        wrote on 14 Apr 2024, 13:41 last edited by
        #3
        This post is deleted!
        1 Reply Last reply
        0

        1/3

        13 Apr 2024, 18:38

        • Login

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