resize Rectangle using 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
Code:
#include "fenetre.h"
#include <QApplication>
int main(int argc, char *argv[])
{
Fenetre w;
w.show();
return a.exec();
}
fenetre.h
Code:
#ifndef FENETRE_H
#define FENETRE_H
#include <QGraphicsScene>
#include <QMainWindow>
#include "myrectangle.h"
#include <QGraphicsView>
#include <QMouseEvent>
#include <QObject>
namespace Ui {
class Fenetre;
}
{
Q_OBJECT
public:
explicit Fenetre
(QWidget *parent
= nullptr
);
~Fenetre();
protected:
private:
Ui::Fenetre *ui;
MyRectangle *rectangle;
signals:
void clickedMouse(int x, int y);
};
#endif // FENETRE_H
fenetre.cpp
Code:
#include "fenetre.h"
#include "ui_fenetre.h"
Fenetre
::Fenetre(QWidget *parent
) : ui(new Ui::Fenetre)
{
ui->setupUi(this);
pen.setWidth(2);
rectangle = new MyRectangle ();
QBrush brush
(c, Qt
::SolidPattern);
scene->setBackgroundBrush(brush);
scene->addItem(rectangle);
scene->setSceneRect(0, 0, 400, 400);
ui->graphicsView->setScene(scene);
view->viewport()->installEventFilter(this);
setCentralWidget(view);
view->show();
connect(this, SIGNAL(clickedMouse(int, int)), rectangle, SLOT(recevedClickedMouse(int, int)));
}
Fenetre::~Fenetre()
{
delete ui;
}
{
if (event
->type
() == QEvent::MouseMove) {
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) {
QMouseEvent *mouseEvent
= static_cast<QMouseEvent
*>
(event
);
statusBar
()->showMessage
(QString("Mouse move (%1,%2)").
arg(mouseEvent
->pos
().
x()).
arg(mouseEvent
->pos
().
y()));
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
Code:
#ifndef MYRECTANGLE_H
#define MYRECTANGLE_H
#include <QPainter>
#include <QGraphicsItem>
#include <QDebug>
#include <QApplication>
#include <QColor>
#include <QPen>
#include <QGraphicsSceneHoverEvent>
#include <QObject>
{
Q_OBJECT
public:
MyRectangle();
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:
protected slots:
void recevedClickedMouse(int x, int y);
};
#endif // MYRECTANGLE_H
myrectangle.cpp
Code:
#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
);
}
{
if(pressedToSize)
{
brush.setColor(color);
}
else
{
brush.setColor(color);
}
painter->fillRect(rec, brush);
painter->drawRect(rec);
}
{
if(event->pos().y() < 10 || event->pos().y() > height - 10)
{
pressedToSize = true;
mouseDownX = event->pos().x();
mouseDownY = event->pos().y();
}
else
{
}
update();
}
{
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 ";
}
}
{
pressedToSize = false;
if((event->pos().y() >= 0 && (event->pos().y() <= 10)) || ((event->pos().y() <= height) && (event->pos().y() >= (height - 10)) ))
{
}
else
{
}
update();
}
{
color = Qt::red;
if((event->pos().y() > 0 && (event->pos().y() < 10)) || ((event->pos().y() < height) && (event->pos().y() > (height - 10)) ))
{
}
else
{
}
update();
}
{
color = Qt::red;
if((event->pos().y() > 0 && (event->pos().y() < 10)) || ((event->pos().y() < height) && (event->pos().y() > (height - 10)) ))
{
}
else
{
}
update();
}
{
color = Qt::green;
if((event->pos().y() >= 0 && (event->pos().y() <= 10)) || ((event->pos().y() <= height) && (event->pos().y() >= height - 10) ))
{
}
else
{
}
update();
}
void MyRectangle::recevedClickedMouse(int x, int y)
{
qDebug() << "7777 x = " << x << "y = " << y << endl;
}
Re: resize Rectangle using mouse events
In your MyRectangle constructor, you have not called either of the base class constructors (QObject, QGraphicsItem), both of which expect a pointer to a parent object (QObject or QGraphicsItem). In any case, there -is- a QGraphicsObject class which inherits from both QObject and QGraphicsItem and you should be using that as your base class if you need signals and slots in your rectangle.
There is a logic error in your code - the mouseReleaseEvent is the only place you set pressToSize back to false. If you press the mouse inside your rectangle, and then release it -outside- the rectangle, then this release event never gets called because the rectangle no longer has the input focus. You should set it to false as the first thing in the mousePressEvent.
Re: resize Rectangle using mouse events
Thank you very much for your answer.
If I do what you say, I get to resize the bottom of the rectangle and at the same time it moves it.
So I found the solution by adding only the function: prepareGeometryChange () at the start of the mouseMoveEvent function.
now it is working properly.