防止QGraphicsItem移出QGraphicsScene

时间:2012-10-27 18:09:32

标签: qt qgraphicsitem qgraphicsscene

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

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

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

我尝试了多种解决方案,例如覆盖QGraphicsItem::itemChange()甚至QGraphicsItem::mouseMoveEvent(),但我仍然无法达到我想要的目标。

适合我需求的解决方案是什么?我是否严重使用QGraphicsItem::itemChange()

提前致谢。

3 个答案:

答案 0 :(得分:11)

您可以像这样覆盖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);
}

答案 1 :(得分:5)

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

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());
    }
}

答案 2 :(得分:1)

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

实际上,Qt Documentation on QGraphicsItem提供了一个示例,它可以准确地解决限制项目移动到场景矩阵的问题:

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);
}

注意我:您必须启用QGraphicsItem::ItemSendsScenePositionChanges标记:

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

注意II:如果您只想对已完成的动作作出反应,请考虑使用GraphicsItemChange标记ItemPositionHasChanged