最近在重构以前写过的软件,遇到一个困扰了我两天的问题。今晚终于发现问题所在并解决,爽~
这个bug出现在:当我使用qt的GraphicsView Framework时,实例化了一个继承自QGraphicsPathItem的对象GraphicsPathItem,我在GraphicsPathItem类内重写了sceneEvent方法,来处理鼠标事件,以画出我想要的形状。但我发现,鼠标事件事件始终不会进入sceneEvent方法中,而在我使用的继承自QGraphicsLineItem类的对象中却工作正常。反复调试,始终找不到问题出在哪里,求助google也无果,没办法,只能看qt的源码。
在QGraphicsScence的mousePressEventHandler方法中,有这么一段代码
if (cachedItemsUnderMouse.isEmpty()) { cachedItemsUnderMouse = itemsAtPosition(
mouseEvent->screenPos(), mouseEvent->scenePos(), mouseEvent->widget()); }
而我的GraphicsPathItem是这样定义的:
penItem = new GraphicsPathItem(QPainterPath(mouseEvent->scenePos()));
在QPainterPath类的说明文档里有这么句话:
A QPainterPath object can be constructed as an empty path, with a given start point.
在QGraphicsPathItem的说明文档中:
QGraphicsPathItem uses the path to provide a reasonable implementation of boundingRect(), shape(), and contains()。
看到这些,可能就有些明白了,我在实例化GraphicsPathItem时,是用一个startPoint实例化的,而当只有一个点时,GraphicsPathItem的path是empty的,而GraphicsPathItem的shape是通过path来确定的,而在GraphicsView Framework中,判断鼠标是否选取了item是通过鼠标的坐标和item的shape来确定的,所以导致当鼠标按下时,itemsAtPosition返回为空,也就导致了,鼠标事件无法通知到GraphicsPathItem对象。
因此,要解决这个问题,重写GraphicsPathItem的shape方法就可以了。
说的不是很清楚,如果有朋友也遇到了这个问题,寻求解决方法,或有更好的解决方法,欢迎讨论~