c++qtcrashqgraphicslineitem

Calling QGraphicsLineItem::boundingRect inside QGraphicsLineItem::shape causes a crash


I am trying to create a drawing application using Qt.

When selecting a shape, I found that the selection range was too limited to the shape, making it difficult to select. Therefore, I overloaded the shape() method of QGraphicsLineItem.

Strangely, as soon as I called the boundingRect() method within shape(), the program immediately crashed:

QPainterPath CLineItem::shape() const
{
    qreal radius = 1.0;

    QPainterPath path;
    path.moveTo(this->line().p1());
    path.lineTo(this->line().p2());

    qDebug() << "test1" << Qt::endl;
    this->boundingRect();
    qDebug() << "test2" << Qt::endl;

    //path.addRect(this->boundingRect().adjusted(-radius, -radius, radius, radius));
    return path;
}

It only outputs "test1", without "test2".


Solution

  • While the documentation says that, by default, shape() calls boundingRect(), most basic QGraphicsItems (including QGraphicsLineItem) actually do the opposite: boundingRect() calls shape(), which will construct a path based on the shape (possibly considering the pen width) and finally returns its controlPointsRect().

    Since you're calling the default boundingRect(), it will attempt to call your shape() override, causing recursion.

    If you want to get a valid path with an increased selection area, then you have two options:

    I would suggest the second option, because shape() is used for collision detection (including mouse event handling) and using the full bounding rect is not a good choice for a line.