2

我认为我的问题与这篇文章类似,但在 C++ 和 QGraphicsItem 中。

我想在另一个 QGraphicsItem 中修复我的对象的可移动区域。如果我试图将它移到外面,我希望我的对象留在里面。

也许这个想法是使用setParentItem().

请问有人知道如何限制 QGraphicsItem 内的可移动区域吗?

4

2 回答 2

5

是的,你是对的。在这里你必须重新实现 itemChange。来自 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);
}

其中 scene() 指的是项目所在的 QGraphicsScene。如果您不使用 QGraphicScene,则必须适当地设置 QRectF(可能来自父项几何)。

于 2014-03-19T18:08:18.047 回答
3

我解决了我的问题!

为此,我添加重新定义如何设置我的QGraphicsItem. 我的项目只是boundingRect()这样定义的:

QRectF MyClass::boundingRect() const
{
return QRectF( -_w/2, -_h/2, _w, _h);
}

所以我想让它QRectF留在场景中。我的项目的位置由 this 的中心定义QRectF。使用@Salvatore Avanzo 提出的 Qt 文档中的代码是我的代码:

QVariant Aabb::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.x() - _w/2, newPos.y() -     _h/2)||!rect.contains(newPos.x() - _w/2, newPos.y() + _h/2)||!rect.contains(newPos.x() + _w/2, newPos.y() + _h/2)||!rect.contains(newPos.x() + _w/2, newPos.y() - _h/2)) 
    {
        // Keep the item inside the scene rect.
        newPos.setX(qMin(rect.right() - _w/2, qMax(newPos.x() , rect.left() + _w/2)));
        newPos.setY(qMin(rect.bottom() - _h/2, qMax(newPos.y() , rect.top() + _h/2)));
        return newPos;
    }


}

return QGraphicsItem::itemChange(change, value);
}

不要忘记设置QRectF场景(请参阅问题中的评论)。

于 2014-03-21T13:11:02.097 回答