最近在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移动前就限制了范围。
希望可以帮助到需要的人☺