Flipping QGraphicsRectItem on mouse move?
-
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".
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.
-
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);
-
This post is deleted!