Problem in drawing Rectangle with mouse event in QGraphicScene

46 Views Asked by At

I have a class for draw rectangle and it works but when dragging rect and start_point(QPoint) is bigger than end_point, current rect won't show.

this clip show what is my problem! enter image description here and the code:

class RectangleScene(QGraphicsScene):
    def __init__(self, *args, **kwargs):
        super(RectangleScene, self).__init__(*args, **kwargs)
        self.graphics_line = None
        self.start_point = QtCore.QPointF()
        self.end_point = QtCore.QPointF()

    def clean_scene(self):
        for index, item in enumerate(self.items()[:-1]):
            if index > 1:


    def mousePressEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self.clean_scene()
            self.start_point = event.scenePos()
            self.end_point = self.start_point
            self.graphics_line = QtWidgets.QGraphicsRectItem(QtCore.QRectF(self.start_point, self.end_point))
            self.addItem(self.graphics_line)
            self.update_path()

        elif QtCore.Qt.RightButton and self.graphics_line:
            self.contextMenuEvent(event)
            super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self.end_point = event.scenePos()
            self.update_path()
            super(RectangleScene, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self.end_point = event.scenePos()
            self.update_path()
            super(RectangleScene, self).mouseReleaseEvent(event)

    def update_path(self):
        if not self.start_point.isNull() and not self.end_point.isNull():
            self.graphics_line.setRect(QtCore.QRectF(self.start_point, self.end_point))
            self.graphics_line.setPen(QPen(
                QColor(242, 219, 7),
                3,
                QtCore.Qt.SolidLine,
                QtCore.Qt.FlatCap,
                QtCore.Qt.RoundJoin,
            ))

but when right click for context menu invisible rect showed.

1

There are 1 best solutions below

0
On BEST ANSWER

You need to normalize your QRectF:

class RectangleScene(QGraphicsScene):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.graphics_line = None
        self.start_point = QPointF()
        self.end_point = QPointF()

    def clean_scene(self):
        for index, item in enumerate(self.items()[:-1]):
            self.removeItem(item)

    def mousePressEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.clean_scene()
            self.start_point = event.scenePos()
            self.end_point = self.start_point
            self.graphics_line = QGraphicsRectItem(
                QRectF(self.start_point, self.end_point).normalized()  # here
            )
            self.addItem(self.graphics_line)
            self.update_path()
        elif Qt.RightButton and self.graphics_line:
            self.contextMenuEvent(event)
            super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.end_point = event.scenePos()
            self.update_path()
        super().mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.end_point = event.scenePos()
            self.update_path()
        super().mouseReleaseEvent(event)

    def update_path(self):
        if not self.start_point.isNull() and not self.end_point.isNull():
            self.graphics_line.setRect(
                QRectF(self.start_point, self.end_point).normalized()  # here
            )
            self.graphics_line.setPen(QPen(
                QColor(242, 219, 7), 3, Qt.SolidLine,
                Qt.FlatCap, Qt.RoundJoin,))