欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

QGraphicsItem设置绘图区域和鼠标响应以及碰撞检测区域,并实现碰撞检测

程序员文章站 2022-07-12 23:03:19
...

QGraphicsItem中有两个方法,分别用来控制QGraphicsItem的绘图区域和碰撞检测区域:
1.[pure virtual] QRectF QGraphicsItem::boundingRect() const
官方文档解释如下:
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);
}
简单来说,通过在继承自QGraphicsItem的子类中重写boundingRect()方法就可以自定义item的绘图区域,QGraphicsView 会根据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().
简单来说这个方法主要用来控制鼠标响应以及碰撞检测区域。

我通过这两个方法实现了如下碰撞检测效果:
QGraphicsItem设置绘图区域和鼠标响应以及碰撞检测区域,并实现碰撞检测

QGraphicsItem设置绘图区域和鼠标响应以及碰撞检测区域,并实现碰撞检测
我的碰撞检测代码如下:

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);//绘制点
}
相关标签: QT qt碰撞检测