关于Qt限制QGraphicsScene内部Item的移动范围

本文讲述了作者在使用QGraphicsScene中QGraphicsPixmapItem时,如何通过`itemChange`函数实时检测位置变化并在移动前限制其范围,解决组件超出指定区域的问题,重点强调了设置`ItemSendsGeometryChanges`标志的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在QGraphicsScene里添加QGraphicsPixmapItem组件(简称Item),且添加后需要限制其范围。刚开始重写了Item的三个鼠标事件。

//鼠标点击事件触发
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    //鼠标移动事件触发
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    //鼠标移动完成事件触发
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

即鼠标判定当前Item的坐标,如果超出自己的区域,则强制SetPos回指定区域。

之后发现效果很不理想,因为判断的前提是Item组件必须先超过一次指定范围。但是我这边的情况不允许它超出,必须在移动前就判定到。

查阅了许多资料发现了个好宝贝,即以下这个函数。
QVariant QGraphicsItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
它能抓取QGraphicsItem的变化,正好PixmapItem继承于QGraphicsItem。
然后再查了下QGraphicsItem::GraphicsItemChange这个参数,里面有个ItemPositionChange,正好可以判定控件是否变化。

QVariant BasePrnHelper::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == ItemPositionChange  &&  scene()) // 控件发生移动
    {
        QPointF newPos = value.toPointF(); //即将要移动的位置
        QRectF rect(0, 0, scene()->width(), scene()->height()); // 你要限制的区域
        if (!rect.contains(newPos)) // 是否在区域内
        {
            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);
}

按照文档的Demo改了下,然后发现Item仍然可以超出范围。
接着我试着打印change,竟然没有触发ItemPostionChange,我再去看了下文档描述。
在这里插入图片描述
发现需要设置ItemSendsGeometryChanges这个flag。

setFlags(QGraphicsItem::ItemIsMovable
 | QGraphicsItem::ItemIsFocusable|
  QGraphicsItem::ItemIsSelectable | 
  QGraphicsItem::ItemSendsGeometryChanges
  ); 

加上了标志位后,成功在Item移动前就限制了范围。

希望可以帮助到需要的人☺

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值