限制QGraphicsItem的可移动区域

7

当设置setFlag(ItemIsMovable)时,有没有一种方法可以限制像QRect这样的QGraphicsItem在移动时的区域?

我是pyqt的新手,正在寻找一种方法来使用鼠标移动项目,并将其限制在垂直/水平方向上。

3个回答

7
如果你想保持一个有限的区域,你可以重新实现ItemChanged()函数。
声明:
#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

实现: 需要使用ItemSendsGeometryChanges标志来捕获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);
}

然后我们定义场景的矩形,这种情况下将会是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);

}

这是为了将图形保持在一个区域内,请加油。


1
它的功能非常好,唯一的问题是Graphic项目可以在右下角被拖出场景一点点,因为你正在使用Graphic框的左上角坐标来验证对象是否在场景矩形内。 - Melroy van den Berg

4
重新实现QGraphicScene中的mouseMoveEvent(self, event)方法,如下所示:
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

希望能对您有所帮助


1

你可能需要重新实现 QGraphicsItemitemChange() 函数。

伪代码:

if (object position does not meet criteria):
    (move the item so its position meets criteria)

重新定位该项将导致再次调用itemChange,但这没关系,因为该项将被正确定位并且不会再次移动,所以您不会陷入无限循环。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接