Точное обнаружение столкновения между двумя графическими элементами - PullRequest
0 голосов
/ 29 апреля 2018

У меня есть два графических элемента, RectItem и CurveItem. Мне нужно точно определить столкновение между этими двумя предметами. Я реализовал для элементов стенда метод shape(). Я проверяю, обнаружено ли столкновение, когда я перемещаю один из предметов со сцены self.collidingItems(self.rect_item, mode=Qt.IntersectsItemShape.

Я сталкиваю предметы, перемещая их в сцене, но столкновение обнаруживается только в верхней части CurveItem. Я не понимаю, где я допустил ошибку.

enter image description here

Код:

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)

1 Ответ

0 голосов
/ 29 апреля 2018

Хотя вы не будете использовать boundingRect() для обнаружения столкновения, вы должны вернуть QRect, который является минимальным размером, охватывающим shape, для этого мы можем использовать boundingRect() метод QPainterPath, кроме того, нет необходимости перезаписывать форму 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)
...