限制qgraphicsitem的可移动区域

发布于 2024-09-15 23:25:29 字数 163 浏览 15 评论 0原文

有没有办法限制设置 setFlag(ItemIsMovable)QGraphicsItem (如 QRect)可以移动的区域?

我是 pyqt 的新手,试图找到一种用鼠标移动项目的方法,并将其限制为仅垂直/水平。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

伤痕我心 2024-09-22 23:25:29

如果您想保留有限的区域,可以重新实现 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);

}

这是为了将图形保持在一个区域内,
祝你好运

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

沙沙粒小 2024-09-22 23:25:29

在 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

希望有帮助

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

甜柠檬 2024-09-22 23:25:29

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

伪代码:

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文