Is there a way to restrict the area where a QGraphicsItem
like QRect
can be moved when setFlag(ItemIsMovable)
is set?
I'm new to pyqt and trying to find a way to move an item with the mouse, and the restrict it to only vertically/horizontally.
Is there a way to restrict the area where a QGraphicsItem
like QRect
can be moved when setFlag(ItemIsMovable)
is set?
I'm new to pyqt and trying to find a way to move an item with the mouse, and the restrict it to only vertically/horizontally.
If you want to keep a limited area you can reimplement the ItemChanged()
Declare:
#ifndef GRAPHIC_H
#define GRAPHIC_H
#include <QGraphicsRectItem>
class Graphic : public QGraphicsRectItem
{
public:
Graphic(const QRectF & rect, QGraphicsItem * parent = 0);
protected:
virtual QVariant itemChange ( GraphicsItemChange change, const QVariant & value );
};
#endif // GRAPHIC_H
implementation : ItemSendsGeometryChanges flag is needed to capture the change in position of QGraphicsItem
#include "graphic.h"
#include <QGraphicsScene>
Graphic::Graphic(const QRectF & rect, QGraphicsItem * parent )
:QGraphicsRectItem(rect,parent)
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsGeometryChanges);
}
QVariant Graphic::itemChange ( GraphicsItemChange change, const QVariant & value )
{
if (change == ItemPositionChange && scene()) {
// value is the new position.
QPointF newPos = value.toPointF();
QRectF rect = scene()->sceneRect();
if (!rect.contains(newPos)) {
// Keep the item inside the scene rect.
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));
newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top())));
return newPos;
}
}
return QGraphicsItem::itemChange(change, value);
}
Then we define the rectangle of the scene, in this case will be 300x300
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QGraphicsView * view = new QGraphicsView(this);
QGraphicsScene * scene = new QGraphicsScene(view);
scene->setSceneRect(0,0,300,300);
view->setScene(scene);
setCentralWidget(view);
resize(400,400);
Graphic * graphic = new Graphic(QRectF(0,0,100,100));
scene->addItem(graphic);
graphic->setPos(150,150);
}
This is to keep the graph within an area, good luck
re implement the mouseMoveEvent(self,event) in the QGraphicScene like the following :
def mousePressEvent(self, event ):
self.lastPoint = event.pos()
def mouseMoveEvent(self, point):
if RestrictedHorizontaly: # boolean to trigger weather to restrict it horizontally
x = point.x()
y = self.lastPoint.y()
self.itemSelected.setPos(QtCore.QPointF(x,y))<br> # which is the QgraphicItem that you have or selected before
hope it helps
You would probably need to re-implement the QGraphicsItem
's itemChange()
function.
Pseudocode:
if (object position does not meet criteria):
(move the item so its position meets criteria)
Repositioning the item will cause itemChange
to get called again, but that's ok because the item will be positioned correctly and won't be moved again, so you'll not be stuck in an endless loop.