QGraphicsItem sets the drawing area, mouse response and collision detection area, and realizes collision detection

There are two methods in QGraphicsItem, which are used to control the drawing area and collision detection area of ​​QGraphicsItem:
1.[pure virtual] QRectF QGraphicsItem::boundingRect() const The
official document explains as follows:
This pure virtual function defines the outer bounds of the item as a rectangle; all painting must be restricted to inside an item's bounding rect. QGraphicsView uses this to determine whether the item requires redrawing.
Although the item's shape can be arbitrary, the bounding rect is always rectangular, and it is unaffected by the items' transformation.
If you want to change the item’s bounding rectangle, you must first call prepareGeometryChange(). This notifies the scene of the imminent change, so that it can update its item geometry index; otherwise, the scene will be unaware of the item’s new geometry, and the results are undefined (typically, rendering artifacts are left within the view).
Reimplement this function to let QGraphicsView determine what parts of the widget, if any, need to be redrawn.
Note: For shapes that paint an outline / stroke, it is important to include half the pen width in the bounding rect. It is not necessary to compensate for antialiasing, though.
Example:

QRectF CircleItem::boundingRect() const
{ qreal penWidth = 1; return QRectF(-radius-penWidth / 2, -radius-penWidth / 2, diameter + penWidth, diameter + penWidth); } Simply put, by inheriting from QGraphicsItem You can customize the drawing area of ​​the item by overriding the boundingRect() method in the subclass of .QGraphicsView will determine which areas need to be redrawn according to boundingRect().




2.[virtual] QPainterPath QGraphicsItem::shape() const
Returns the shape of this item as a QPainterPath in local coordinates. The shape is used for many things, including collision detection, hit tests, and for the QGraphicsScene::items() functions.
The default implementation calls boundingRect() to return a simple rectangular shape, but subclasses can reimplement this function to return a more accurate shape for non-rectangular items. For example, a round item may choose to return an elliptic shape for better collision detection. For example:

QPainterPath RoundItem::shape() const
{
QPainterPath path;
path.addEllipse(boundingRect());
return path;
}

The outline of a shape can vary depending on the width and style of the pen used when drawing. If you want to include this outline in the item's shape, you can create a shape from the stroke using QPainterPathStroker.
This function is called by the default Implementations of contains() and collidesWithPath().
Simply put, this method is mainly used to control the mouse response and collision detection area.

I achieved the following collision detection effects through these two methods:
Insert picture description here

Insert picture description here
My collision detection code is as follows:

void myGraphicRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    
    
    QPen mPen;
    if(!this->scene()->collidingItems(this).isEmpty())//有重叠
    {
    
    
        mPen= QPen(Qt::red);
    }
    else
    {
    
    
        mPen= QPen(Qt::yellow);
    }
    painter->setPen(mPen);
    //绘制旋转后的矩形
    painter->drawPolygon(m_oldRectPolygon);
    //绘制旋转圆形
    mPen.setWidth(2);
    mPen.setColor(Qt::green);
    painter->setPen(mPen);
    QPointF pf = getSmallRotateRectCenter(m_oldRectPolygon[0],m_oldRectPolygon[1]);
    QRectF rect = QRectF(pf.x()-10,pf.y()-10,20,20);
    painter->drawEllipse(rect);//绘制圆形
    painter->drawPoint(pf);//绘制点
}

Guess you like

Origin blog.csdn.net/weixin_43935474/article/details/107056569