最近在重構以前寫過的軟件,遇到一個困擾了我兩天的問題。今晚終於發現問題所在並解決,爽~
這個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方法就可以了。
說的不是很清楚,如果有朋友也遇到了這個問題,尋求解決方法,或有更好的解決方法,歡迎討論~