Qt:限制QGraphicsItem在另一个QGraphicsItem中的可移动区域

Qt: restrict movable area of a QGraphicsItem inside an other QGraphicsItem C++

本文关键字:QGraphicsItem 可移动 区域 限制 Qt 另一个      更新时间:2023-10-16

我认为我的问题类似于这篇文章,但在c++和QGraphicsItem内。

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

也许我们的想法是使用setParentItem()

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

是的,你是正确的。在这里,你必须重新实现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(可能从父项目几何)。

我的问题解决了!

为此,我添加了重新定义如何设置QGraphicsItem的位置。我的条目是由boundingRect()定义的,像这样:

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

所以我想让这个QRectF留在场景中。我的项目的位置是由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(参见问题中的评论)