14

我有一个固定尺寸从 (0;0) 到 (481;270) 的场景:

scene->setSceneRect(0, 0, 481, 270);

在其中,我有一个自定义GraphicsItem,我可以通过 flag 移动它ItemisMovable,但我希望它留在场景中;我实际上的意思是我不希望它的坐标既不低于 (0;0) 也不高于 (481;270)。

我尝试了几种解决方案,例如覆盖QGraphicsItem::itemChange()或什QGraphicsItem::mouseMoveEvent()至,但我仍然无法达到我想要做的事情。

什么是适合我需求的解决方案?我用QGraphicsItem::itemChange()得不好?

提前致谢。

4

3 回答 3

13

您可以像这样覆盖QGraphicsItem::mouseMoveEvent()

YourItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    QGraphicsItem::mouseMoveEvent(event); // move the item...

    // ...then check the bounds
    if (x() < 0)
        setPos(0, y());
    else if (x() > 481)
        setPos(481, y());

    if (y() < 0)
        setPos(x(), 0);
    else if (y() > 270)
        setPos(x(), 270);
}
于 2012-10-27T18:33:10.063 回答
7

此代码将您的完整项目保留在场景中。不仅是您项目的左上角像素。

void YourItem::mouseMoveEvent( QGraphicsSceneMouseEvent *event )
{
    QGraphicsItem::mouseMoveEvent(event); 

    if (x() < 0)
    {
        setPos(0, y());
    }
    else if (x() + boundingRect().right() > scene()->width())
    {
        setPos(scene()->width() - boundingRect().width(), y());
    }

    if (y() < 0)
    {
        setPos(x(), 0);
    }
    else if ( y()+ boundingRect().bottom() > scene()->height())
    {
        setPos(x(), scene()->height() - boundingRect().height());
    }
}
于 2014-11-13T09:41:02.077 回答
5

警告:建议的解决方案不适用于多选项目。问题是,在这种情况下,只有一个项目会收到鼠标移动事件。

实际上,QGraphicsItem 上的 Qt 文档提供了一个示例,该示例正好解决了将项目移动限制到场景矩形的问题:

QVariant Component::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);
}

注意 I:您必须启用该QGraphicsItem::ItemSendsScenePositionChanges标志:

item->setFlags(QGraphicsItem::ItemIsMovable
               | QGraphicsItem::ItemIsSelectable
               | QGraphicsItem::ItemSendsScenePositionChanges);

注意二:如果你只想对完成的动作做出反应,考虑使用GraphicsItemChange标志ItemPositionHasChanged

于 2017-12-20T13:08:44.690 回答