在QGraphicsLineItem::shape中调用boundingRect致程序崩溃求助
Qt绘图应用shape()调用boundingRect()崩溃的解决方案
崩溃原因
最可能是无限递归调用导致栈溢出:如果你的CLineItem同时重载了boundingRect(),且在该方法里调用了shape(),那么shape()调用boundingRect()时就会触发循环调用,直接撑爆程序栈。哪怕你没显式重载boundingRect(),如果继承链里有其他类重载了该方法并依赖shape(),也会出现这个问题。
另外,QGraphicsLineItem的默认boundingRect()逻辑很简单,完全可以手动实现,没必要调用原方法,这样能彻底规避递归风险。
修复后的代码
直接手动计算线条的包围盒,替代调用boundingRect(),同时实现扩大选择范围的需求:
QPainterPath CLineItem::shape() const { const qreal expandRadius = 1.0; // 扩大选择范围的半径 const QLineF line = this->line(); // 手动计算线条的包围盒,和QGraphicsLineItem默认逻辑一致 const qreal left = qMin(line.p1().x(), line.p2().x()); const qreal right = qMax(line.p1().x(), line.p2().x()); const qreal top = qMin(line.p1().y(), line.p2().y()); const qreal bottom = qMax(line.p1().y(), line.p2().y()); const QRectF lineRect(left, top, right - left, bottom - top); QPainterPath path; // 把包围盒向外扩展,扩大可点击范围 path.addRect(lineRect.adjusted(-expandRadius, -expandRadius, expandRadius, expandRadius)); return path; }
额外验证建议
如果怀疑是递归问题,可以在boundingRect()(如果你重载了)里加qDebug输出,看崩溃前是否会反复打印同一内容,确认循环调用的存在。
内容的提问来源于stack exchange,提问作者Natural_User
相关产品推荐
相关产品推荐

