Resize rectangle with mouse events
-
Hi
I'm trying to resize a rectangle and move it with the mouse.
at the moment i managed to move it with the mouse but i have a little problem resizing it.
When I resize it from the top of the rectangle, I have no problem but when I resize it from the bottom, I manage to do it as long as I don't release the mouse button but once release it, I can't resize it anymore until I move the rectangle.
In addition, there are traces in the window when I decrease the height of the bottom rectangle.
can you help me find where the bug is coming from?```
main.cpp
#include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Fenetre w; w.show(); return a.exec(); }fenetre.h
#ifndef FENETRE_H #define FENETRE_H #include <QGraphicsScene> #include <QMainWindow> #include "myrectangle.h" #include <QGraphicsView> #include <QMouseEvent> #include <QObject> namespace Ui { class Fenetre; } class Fenetre : public QMainWindow { Q_OBJECT public: explicit Fenetre(QWidget *parent = nullptr); ~Fenetre(); bool eventFilter(QObject *obj, QEvent *event); protected: private: Ui::Fenetre *ui; QGraphicsScene *scene; QGraphicsView *view; MyRectangle *rectangle; signals: void clickedMouse(int x, int y); }; #endif // FENETRE_Hfenetre.cpp
#include "fenetre.h" #include "ui_fenetre.h" Fenetre::Fenetre(QWidget *parent) : QMainWindow(parent), ui(new Ui::Fenetre) { ui->setupUi(this); QBrush greenBrush(Qt::green); QBrush blueBrush(Qt::blue); QPen pen(Qt::black); pen.setWidth(2); rectangle = new MyRectangle (); QColor c (242,251,235); QBrush brush (c, Qt::SolidPattern); scene = new QGraphicsScene(this); scene->setBackgroundBrush(brush); scene->addItem(rectangle); view = new QGraphicsView(scene); scene->setSceneRect(0, 0, 400, 400); ui->graphicsView->setScene(scene); view->viewport()->installEventFilter(this); // Meilleur Fonctionne // view->installEventFilter(this); // Fonctionne // ui->graphicsView->viewport()->installEventFilter(this); setCentralWidget(view); view->show(); connect(this, SIGNAL(clickedMouse(int, int)), rectangle, SLOT(recevedClickedMouse(int, int))); } Fenetre::~Fenetre() { delete ui; } bool Fenetre::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseMove) { // qDebug() << "AAAAAA eventFilter MouseMove" << endl; QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); statusBar()->showMessage(QString("Mouse move (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y())); // emit clickedMouse(mouseEvent->pos().x(), mouseEvent->pos().y()); } else if (event->type() == QEvent::MouseButtonPress) { qDebug() << "BBBBBB eventFilter MouseButtonPress " << endl; QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); statusBar()->showMessage(QString("Mouse move (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y())); /////////////////////////// // qDebug() << "rectangle->pos().x() " << rectangle->pos().x() << "rectangle->pos().y()" << rectangle->pos().y() << endl; // qDebug() << "rectangle->scenePos().x() " << rectangle->scenePos().x() << "rectangle->scenePos().y()" << rectangle->scenePos().y() << endl; // QPoint point_mouse_move = ui->graphicsView->mapFrom(ui->graphicsView, QPoint(rectangle->pos().x(), rectangle->pos().y())); // qDebug() << "OK 1111 BBB ui->graphicsView->mapFrom(point_mouse_move.x() = " << point_mouse_move.x() << "point_mouse_move.y() " << point_mouse_move.y();//okkk INUTILE QPoint pointRec2 = view->mapFromScene(rectangle->pos().x(), rectangle->pos().y()); qDebug() << "OKKKKKK 2222 BBBBBB view->mapFromScene(myRect.x() = " << pointRec2.x() << "myRect.y() " << pointRec2.y(); //okkk IMPORTANT /////////////////////////// emit clickedMouse(mouseEvent->pos().x(), mouseEvent->pos().y()); } return false; }myrectangle.h
#ifndef MYRECTANGLE_H #define MYRECTANGLE_H #include <QPainter> #include <QGraphicsItem> #include <QDebug> #include <QApplication> #include <QColor> #include <QPen> #include <QGraphicsSceneHoverEvent> #include <QObject> class MyRectangle : public QObject, public QGraphicsItem { Q_OBJECT public: MyRectangle(); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QColor color; // the hover event handlers will toggle this between red and black QPen pen; // the pen is used to paint the red/black border private: qreal width; qreal height; int mouseDownX; int mouseDownY; bool pressedToSize; int avant = 0; protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverMoveEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); protected slots: void recevedClickedMouse(int x, int y); }; #endif // MYRECTANGLE_Hmyrectangle.cpp
#include "myrectangle.h" MyRectangle::MyRectangle() { width = 100; height = 50; pressedToSize = false; setFlag(ItemIsMovable); setAcceptHoverEvents(true); color = Qt::yellow; pen.setColor(color); } QRectF MyRectangle::boundingRect() const { return QRectF(0, 0, width, height); } void MyRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { QRectF rec = boundingRect(); QBrush brush(Qt::blue); if(pressedToSize) { brush.setColor(color); } else { brush.setColor(color); } painter->fillRect(rec, brush); painter->drawRect(rec); } void MyRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event) { // qDebug() << "mousePressEvent" << endl; qDebug() << "PPPPPPPP mousePressEvent event->pos().x() = " << event->pos().x() << "event->pos().y() = "<< event->pos().y() << endl; if(event->pos().y() < 10 || event->pos().y() > height - 10) { pressedToSize = true; QApplication::setOverrideCursor(Qt::SizeVerCursor); mouseDownX = event->pos().x(); mouseDownY = event->pos().y(); } else { QApplication::setOverrideCursor(Qt::OpenHandCursor); } update(); QGraphicsItem::mousePressEvent(event); // OK Décomenter } void MyRectangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { // qDebug() << ">>>>>>> mouseMoveEvent() width() = " << width << "height = "<< height; qDebug() << ">>>>>>> mouseMoveEvent() par rapport à lui meme event->pos().x() = " << event->pos().x() << "event->pos().y() = "<< event->pos().y(); qDebug() << ">>>>>>> position du rectangle par rapport à la scene this->pos().x() = " << this->pos().x() << "this->pos().y() = " << this->pos().y(); // qDebug() << ">>>>>>> mouseMoveEvent mouseDownX = " << mouseDownX << "mouseDownY = "<< mouseDownY << endl << endl; if(pressedToSize) { if((mouseDownY <= 10)) // En haut du rectangle { qDebug() << "haut "; height -= event->pos().y(); // setPos(pos().x() , pos().y() + event->pos().y() ); moveBy(0, event->pos().y()); } else if( (avant >= height -10)) // En bas du rectangle { qDebug() << "bas "; height = event->pos().y(); // setPos(pos().x() , pos().y()); // moveBy(0, 0); } } avant = event->pos().y(); update(); if(!pressedToSize) { qDebug() << "!!!!!pressedToSize "; QGraphicsItem::mouseMoveEvent(event); //Decommenter si setFlag(ItemIsMovable) } } void MyRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { pressedToSize = false; if((event->pos().y() >= 0 && (event->pos().y() <= 10)) || ((event->pos().y() <= height) && (event->pos().y() >= (height - 10)) )) { // qDebug() << "mouseReleaseEvent width, height" << width << height << endl; QApplication::setOverrideCursor(Qt::SizeVerCursor); } else { QApplication::setOverrideCursor(Qt::OpenHandCursor); } update(); QGraphicsItem::mouseReleaseEvent(event); // OK } void MyRectangle::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { // qDebug() << ">>>>>>>>>>>>>>> hoverEnterEvent x() = " << event->pos().x() << "y() = " << event->pos().y() << endl; color = Qt::red; if((event->pos().y() > 0 && (event->pos().y() < 10)) || ((event->pos().y() < height) && (event->pos().y() > (height - 10)) )) { QApplication::setOverrideCursor(Qt::SizeVerCursor); } else { QApplication::setOverrideCursor(Qt::OpenHandCursor); } update(); } void MyRectangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { // qDebug() << ">>>>>>>>>>>>>>> hoverMoveEvent x() = " << event->pos().x() << "y() = " << event->pos().y() ; // qDebug() << ">>>>>>>>>>>>>>> hoverMoveEvent mouseDownX = " << mouseDownX << "mouseDownY = " << mouseDownY << endl; // qDebug() << ">>>>>>>>>>>>>>> hoverMoveEvent x() = width << height " << width << height << endl; color = Qt::red; if((event->pos().y() > 0 && (event->pos().y() < 10)) || ((event->pos().y() < height) && (event->pos().y() > (height - 10)) )) { QApplication::setOverrideCursor(Qt::SizeVerCursor); } else { QApplication::setOverrideCursor(Qt::OpenHandCursor); } update(); } void MyRectangle::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { // qDebug() << ">>>>>>>>>>>>>>> hoverLeaveEvent x() = " << event->pos().x() << "y() = " << event->pos().y() << endl; color = Qt::green; if((event->pos().y() >= 0 && (event->pos().y() <= 10)) || ((event->pos().y() <= height) && (event->pos().y() >= height - 10) )) { QApplication::setOverrideCursor(Qt::SizeVerCursor); } else { QApplication::setOverrideCursor(Qt::ArrowCursor); } update(); } void MyRectangle::recevedClickedMouse(int x, int y) { qDebug() << "7777 COUCOU x = " << x << "y = " << y << endl; } -
Hi
I'm trying to resize a rectangle and move it with the mouse.
at the moment i managed to move it with the mouse but i have a little problem resizing it.
When I resize it from the top of the rectangle, I have no problem but when I resize it from the bottom, I manage to do it as long as I don't release the mouse button but once release it, I can't resize it anymore until I move the rectangle.
In addition, there are traces in the window when I decrease the height of the bottom rectangle.
can you help me find where the bug is coming from?```
main.cpp
#include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Fenetre w; w.show(); return a.exec(); }fenetre.h
#ifndef FENETRE_H #define FENETRE_H #include <QGraphicsScene> #include <QMainWindow> #include "myrectangle.h" #include <QGraphicsView> #include <QMouseEvent> #include <QObject> namespace Ui { class Fenetre; } class Fenetre : public QMainWindow { Q_OBJECT public: explicit Fenetre(QWidget *parent = nullptr); ~Fenetre(); bool eventFilter(QObject *obj, QEvent *event); protected: private: Ui::Fenetre *ui; QGraphicsScene *scene; QGraphicsView *view; MyRectangle *rectangle; signals: void clickedMouse(int x, int y); }; #endif // FENETRE_Hfenetre.cpp
#include "fenetre.h" #include "ui_fenetre.h" Fenetre::Fenetre(QWidget *parent) : QMainWindow(parent), ui(new Ui::Fenetre) { ui->setupUi(this); QBrush greenBrush(Qt::green); QBrush blueBrush(Qt::blue); QPen pen(Qt::black); pen.setWidth(2); rectangle = new MyRectangle (); QColor c (242,251,235); QBrush brush (c, Qt::SolidPattern); scene = new QGraphicsScene(this); scene->setBackgroundBrush(brush); scene->addItem(rectangle); view = new QGraphicsView(scene); scene->setSceneRect(0, 0, 400, 400); ui->graphicsView->setScene(scene); view->viewport()->installEventFilter(this); // Meilleur Fonctionne // view->installEventFilter(this); // Fonctionne // ui->graphicsView->viewport()->installEventFilter(this); setCentralWidget(view); view->show(); connect(this, SIGNAL(clickedMouse(int, int)), rectangle, SLOT(recevedClickedMouse(int, int))); } Fenetre::~Fenetre() { delete ui; } bool Fenetre::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseMove) { // qDebug() << "AAAAAA eventFilter MouseMove" << endl; QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); statusBar()->showMessage(QString("Mouse move (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y())); // emit clickedMouse(mouseEvent->pos().x(), mouseEvent->pos().y()); } else if (event->type() == QEvent::MouseButtonPress) { qDebug() << "BBBBBB eventFilter MouseButtonPress " << endl; QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); statusBar()->showMessage(QString("Mouse move (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y())); /////////////////////////// // qDebug() << "rectangle->pos().x() " << rectangle->pos().x() << "rectangle->pos().y()" << rectangle->pos().y() << endl; // qDebug() << "rectangle->scenePos().x() " << rectangle->scenePos().x() << "rectangle->scenePos().y()" << rectangle->scenePos().y() << endl; // QPoint point_mouse_move = ui->graphicsView->mapFrom(ui->graphicsView, QPoint(rectangle->pos().x(), rectangle->pos().y())); // qDebug() << "OK 1111 BBB ui->graphicsView->mapFrom(point_mouse_move.x() = " << point_mouse_move.x() << "point_mouse_move.y() " << point_mouse_move.y();//okkk INUTILE QPoint pointRec2 = view->mapFromScene(rectangle->pos().x(), rectangle->pos().y()); qDebug() << "OKKKKKK 2222 BBBBBB view->mapFromScene(myRect.x() = " << pointRec2.x() << "myRect.y() " << pointRec2.y(); //okkk IMPORTANT /////////////////////////// emit clickedMouse(mouseEvent->pos().x(), mouseEvent->pos().y()); } return false; }myrectangle.h
#ifndef MYRECTANGLE_H #define MYRECTANGLE_H #include <QPainter> #include <QGraphicsItem> #include <QDebug> #include <QApplication> #include <QColor> #include <QPen> #include <QGraphicsSceneHoverEvent> #include <QObject> class MyRectangle : public QObject, public QGraphicsItem { Q_OBJECT public: MyRectangle(); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QColor color; // the hover event handlers will toggle this between red and black QPen pen; // the pen is used to paint the red/black border private: qreal width; qreal height; int mouseDownX; int mouseDownY; bool pressedToSize; int avant = 0; protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverMoveEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); protected slots: void recevedClickedMouse(int x, int y); }; #endif // MYRECTANGLE_Hmyrectangle.cpp
#include "myrectangle.h" MyRectangle::MyRectangle() { width = 100; height = 50; pressedToSize = false; setFlag(ItemIsMovable); setAcceptHoverEvents(true); color = Qt::yellow; pen.setColor(color); } QRectF MyRectangle::boundingRect() const { return QRectF(0, 0, width, height); } void MyRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { QRectF rec = boundingRect(); QBrush brush(Qt::blue); if(pressedToSize) { brush.setColor(color); } else { brush.setColor(color); } painter->fillRect(rec, brush); painter->drawRect(rec); } void MyRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event) { // qDebug() << "mousePressEvent" << endl; qDebug() << "PPPPPPPP mousePressEvent event->pos().x() = " << event->pos().x() << "event->pos().y() = "<< event->pos().y() << endl; if(event->pos().y() < 10 || event->pos().y() > height - 10) { pressedToSize = true; QApplication::setOverrideCursor(Qt::SizeVerCursor); mouseDownX = event->pos().x(); mouseDownY = event->pos().y(); } else { QApplication::setOverrideCursor(Qt::OpenHandCursor); } update(); QGraphicsItem::mousePressEvent(event); // OK Décomenter } void MyRectangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { // qDebug() << ">>>>>>> mouseMoveEvent() width() = " << width << "height = "<< height; qDebug() << ">>>>>>> mouseMoveEvent() par rapport à lui meme event->pos().x() = " << event->pos().x() << "event->pos().y() = "<< event->pos().y(); qDebug() << ">>>>>>> position du rectangle par rapport à la scene this->pos().x() = " << this->pos().x() << "this->pos().y() = " << this->pos().y(); // qDebug() << ">>>>>>> mouseMoveEvent mouseDownX = " << mouseDownX << "mouseDownY = "<< mouseDownY << endl << endl; if(pressedToSize) { if((mouseDownY <= 10)) // En haut du rectangle { qDebug() << "haut "; height -= event->pos().y(); // setPos(pos().x() , pos().y() + event->pos().y() ); moveBy(0, event->pos().y()); } else if( (avant >= height -10)) // En bas du rectangle { qDebug() << "bas "; height = event->pos().y(); // setPos(pos().x() , pos().y()); // moveBy(0, 0); } } avant = event->pos().y(); update(); if(!pressedToSize) { qDebug() << "!!!!!pressedToSize "; QGraphicsItem::mouseMoveEvent(event); //Decommenter si setFlag(ItemIsMovable) } } void MyRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { pressedToSize = false; if((event->pos().y() >= 0 && (event->pos().y() <= 10)) || ((event->pos().y() <= height) && (event->pos().y() >= (height - 10)) )) { // qDebug() << "mouseReleaseEvent width, height" << width << height << endl; QApplication::setOverrideCursor(Qt::SizeVerCursor); } else { QApplication::setOverrideCursor(Qt::OpenHandCursor); } update(); QGraphicsItem::mouseReleaseEvent(event); // OK } void MyRectangle::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { // qDebug() << ">>>>>>>>>>>>>>> hoverEnterEvent x() = " << event->pos().x() << "y() = " << event->pos().y() << endl; color = Qt::red; if((event->pos().y() > 0 && (event->pos().y() < 10)) || ((event->pos().y() < height) && (event->pos().y() > (height - 10)) )) { QApplication::setOverrideCursor(Qt::SizeVerCursor); } else { QApplication::setOverrideCursor(Qt::OpenHandCursor); } update(); } void MyRectangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { // qDebug() << ">>>>>>>>>>>>>>> hoverMoveEvent x() = " << event->pos().x() << "y() = " << event->pos().y() ; // qDebug() << ">>>>>>>>>>>>>>> hoverMoveEvent mouseDownX = " << mouseDownX << "mouseDownY = " << mouseDownY << endl; // qDebug() << ">>>>>>>>>>>>>>> hoverMoveEvent x() = width << height " << width << height << endl; color = Qt::red; if((event->pos().y() > 0 && (event->pos().y() < 10)) || ((event->pos().y() < height) && (event->pos().y() > (height - 10)) )) { QApplication::setOverrideCursor(Qt::SizeVerCursor); } else { QApplication::setOverrideCursor(Qt::OpenHandCursor); } update(); } void MyRectangle::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { // qDebug() << ">>>>>>>>>>>>>>> hoverLeaveEvent x() = " << event->pos().x() << "y() = " << event->pos().y() << endl; color = Qt::green; if((event->pos().y() >= 0 && (event->pos().y() <= 10)) || ((event->pos().y() <= height) && (event->pos().y() >= height - 10) )) { QApplication::setOverrideCursor(Qt::SizeVerCursor); } else { QApplication::setOverrideCursor(Qt::ArrowCursor); } update(); } void MyRectangle::recevedClickedMouse(int x, int y) { qDebug() << "7777 COUCOU x = " << x << "y = " << y << endl; }@coder2020 said in Resize rectangle with mouse events:
In addition, there are traces in the window when I decrease the height of the bottom rectangle.
can you help me find where the bug is coming from?Without looking into your code, I can say, that it's not a bug.
Try to call
prepareGeometryChange()before changing your item size.
https://doc.qt.io/qt-5/qgraphicsitem.html#prepareGeometryChange -
@coder2020 said in Resize rectangle with mouse events:
In addition, there are traces in the window when I decrease the height of the bottom rectangle.
can you help me find where the bug is coming from?Without looking into your code, I can say, that it's not a bug.
Try to call
prepareGeometryChange()before changing your item size.
https://doc.qt.io/qt-5/qgraphicsitem.html#prepareGeometryChange