Reputation: 519
I have two graphics items, RectItem
and CurveItem
. I need to detect precisely the collision between these two items. I implemented for booth items the shape()
method. I verify if collision is detected when I move one of the items from scene self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape
.
I collide the items by moving them in the scene, but the collision is detected only on top part of the CurveItem
. I don't understand where I made a mistake.
Code:
class RectItem(QGraphicsRectItem):
def __init__(self, x, y, w, h):
super().__init__(x, y, w, h)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setPen(QPen(Qt.cyan))
def shape(self):
path = QPainterPath()
path.addRect(self.boundingRect())
return path
class CurveItem(QGraphicsItem):
def __init__(self):
super().__init__()
self.path = self._setupPath()
def paint(self, painter, styles, widget=None):
painter.drawPath(self.path)
def boundingRect(self):
return QRectF()
def shape(self):
return self.path
def _setupPath(self):
path = QPainterPath()
path.moveTo(0, 0)
path.cubicTo(99, 0, 50, 50, 99, 99)
path.cubicTo(0, 99, 50, 50, 0, 0)
return path
class Scene(QGraphicsScene):
def __init__(self):
super().__init__()
self.curve_item = CurveItem()
self.rect_item = RectItem(-50, -50, 25, 25)
self.addItem(self.curve_item)
self.addItem(self.rect_item)
def mouseMoveEvent(self, e):
print(self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape))
super().mouseMoveEvent(e)
Upvotes: 0
Views: 1674
Reputation: 244122
Although you will not use the boundingRect()
to detect the collision you must return a QRect
that is the minimum size that covers the shape
, for this we can use the boundingRect()
method of QPainterPath
, besides it is not necessary to overwrite the shape QGraphicsRectItem
.
class RectItem(QGraphicsRectItem):
def __init__(self, *args):
super().__init__(*args)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setPen(QPen(Qt.cyan))
class CurveItem(QGraphicsItem):
def __init__(self):
super().__init__()
self.path = self._setupPath()
def paint(self, painter, styles, widget=None):
painter.drawPath(self.path)
def boundingRect(self):
return self.path.boundingRect()
def shape(self):
return self.path
def _setupPath(self):
path = QPainterPath()
path.moveTo(0, 0)
path.cubicTo(99, 0, 50, 50, 99, 99)
path.cubicTo(0, 99, 50, 50, 0, 0)
return path
class Scene(QGraphicsScene):
def __init__(self):
super().__init__()
self.curve_item = CurveItem()
self.rect_item = RectItem(-50, -50, 25, 25)
self.addItem(self.curve_item)
self.addItem(self.rect_item)
def mouseMoveEvent(self, e):
print(self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape))
super().mouseMoveEvent(e)
Upvotes: 1