Qt中基于QGraphicsItem类的重载鼠标事件函数的教训

时间:2023-02-03 12:12:23

Qt中基于QGraphicsItem类的重载鼠标事件函数的教训

最近还是在折腾俄罗斯方块的游戏,在这里把遇到的一个问题进行记录一下,作为一个学习笔记,以便以后查找,问题是这样的:因为游戏的背景要分为几个层,这些层都是基于QGraphicsItem类实现的。我在最上层移动鼠标,却在次上层也响应啦鼠标事件,而我就是不想要次上层响应鼠标事件。
为啦把问题描述的更加清楚,我们用一个简单的例子描述下,比如说下图1一个按钮的图标。

Qt中基于QGraphicsItem类的重载鼠标事件函数的教训

图1

图2是弹出的一个游戏结束的图层,应该在上面的这个图标的上一层显示。

Qt中基于QGraphicsItem类的重载鼠标事件函数的教训

图2

图3是这两个图层显示的一个示意图,为了让大家更加明确,我们把显示的左边做啦一点点得调整。图1是在下层,图2在上层显示。

Qt中基于QGraphicsItem类的重载鼠标事件函数的教训

图3

图4中深蓝色部分就是上下两层图片重合的区域。

Qt中基于QGraphicsItem类的重载鼠标事件函数的教训

图4

我们的问题就是在这个重合区域里,移动鼠标,下层却会响应鼠标的以下两个事件。

void QGraphicsItem::hoverEnterEvent ( QGraphicsSceneHoverEvent * event ) 
void QGraphicsItem::hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )

刚开始一直很纠结,不知道是怎么回事,之后在一个前辈的指点下,又认真看啦看qt的帮助文档如下:

void QGraphicsItem::mousePressEvent ( QGraphicsSceneMouseEvent * event )   [virtual protected]
This event handler, for event event, can be reimplemented to receive mouse press events for this item. Mouse press events are only delivered to items that accept the mouse button that is pressed. By default, an item accepts all mouse buttons, but you can change this by calling setAcceptedMouseButtons().

The mouse press event decides which item should become the mouse grabber (see QGraphicsScene::mouseGrabberItem()). If you do not reimplement this function, the press event will propagate to any topmost item beneath this item, and no other mouse events will be delivered to this item.

If you do reimplement this function, event will by default be accepted (see QEvent::accept()), and this item is then the mouse grabber. This allows the item to receive future move, release and doubleclick events. If you call QEvent::ignore() on event, this item will lose the mouse grab, and event will propagate to any topmost item beneath. No further mouse events will be delivered to this item unless a new mouse press event is received.

The default implementation handles basic item interaction, such as selection and moving. If you want to keep the base implementation when reimplementing this function, call QGraphicsItem::mousePressEvent() in your reimplementation.

The event is QEvent::ignore()d for items that are neither movable nor selectable.

See also mouseMoveEvent(), mouseReleaseEvent(), mouseDoubleClickEvent(), and sceneEvent().

这上面的两句标注啦的,说的很清楚,如果你最上面一层没有接受鼠标事件,其会传到次上层去处理,如果次上层也没有接受鼠标事件,则再向下传,最后一直到最底层的,如果最底层也不接受鼠标事件,则会传到Scene(场景)中去处理,如果Scene(场景)中也不处理则会丢弃,而不是传给View。这个是我用例子测试过的。如果有什么错误,还请大家指出。谢谢。
我做啦一个简单的测试例子,放在 http://download.csdn.net/detail/xj178926426/3940751
大家感兴趣可以到下下来试试。