QGraphicsSceneBspTree出现的崩溃问题

QGraphicsSceneBspTree出现的崩溃问题

现象描述:在移动或修改了某个图元之后,鼠标在界面上移动后会出现崩溃,提示信息如下:

QGraphicsSceneBspTree出现的崩溃问题_第1张图片

崩溃点会发生在QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor*)附近
这个问题其实是因为修改图元的BoundingBox时没有预先通知Scene,使得其通过Bsp树查找图元信息时出错导致的。
一个典型的错误代码如下:

QRectF GFYLineGraphicsItem::boundingRect() const
{
    return shape().boundingRect();
}

QPainterPath GFYLineGraphicsItem::shape() const
{
    QPainterPath oPath;    
    CLine lineData = m_LineInfo->lineData();
    oPath.addLine(lineData.beginPoint(),lineData.endPoint());
    return shapeFromPath(oPath, pen());
}
   如代码所示, 这个从QGraphicsItem继承来的GFYLineGraphicsItem的shape()函数中,其shape其实是受数据CLine lineData控制的。写这段代码的同学意思是想通过修改m_LineInfo的lineData即可改变GFYLineGraphicsItem的长度或位置,然后boundingRect直接使用了shape的外接矩形。但是按照QT的要求,在修改QGraphicsItem的boundingRect时,必须加上prepareGeometryChange(),来保证QGraphicsScene的index是最新的。不然就会出现开头的错误。

  所以这段代码中应将动态改变shape的部分去掉,比如新写一个changeGeometry()函数:
void GFYLineGraphicsItem::changeGeometry()
{
    prepareGeometryChange();
    Qline line(lineData.beginPoint(),lineData.endPoint());
    setLine(line);
}
然后当m_LineInfo->lineData()的数据变化时,通过某种方式调用GFYLineGraphicsItem::changeGeometry()即可
规避此问题。
google上的回答:
Crash in QGraphicsSceneBspTree when adding items in response to a mouse press and adjusting them when moving.
Resolution: Always call prepareGeometryChange() before changing the item's geometry. Otherwise, the scene's index will fall out of sync, and the behavior is undefined.

你可能感兴趣的:(QT,qt,GUI)