ObtainNalgene
ObtainNalgene

Reputation: 13

How to erase point in PyQt5 QPainter?

I want to display the x and y coordinates from an accelerometer on an image. I used QPainter to set up the image and the drawPoint function to draw the coordinate at the given point. When the new coordinate is drawn, I need to erase the old coordinate so that there is only one at a time. In the code below, I called drawCoordinate twice, what happens is the target image ends up with 2 coordinate points at 0,0 and 0.5,0.5 but ideally I would be left with the last drawn coordinate.

This is my first question on here so I hope my format is correct! Let me know if I need to fix anything to help with clarity.

target image with 2 coordinates


class Target(QWidget):

    def __init__(self):
        super().__init__()
        self.drawing = False
        self.image = QPixmap(r"Pictures\target_png_300.png")
        self.setGeometry(0, 0, 300, 300)
        self.resize(self.image.width(), self.image.height())
        self.show()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(self.rect(), self.image)
    
    def paintCoordinate(self, x, y):
        painter = QPainter(self.image)
        r = QRect(-1, -1, 2, 2)
        painter.setWindow(r)
        pen = QPen(Qt.black, 0.06, Qt.DotLine, Qt.RoundCap)
        painter.setPen(pen)
        painter.drawPoint(QPointF(x, y))

if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Target()
    ex.paintCoordinate(0, 0)
    ex.paintCoordinate(0.5, 0.5)
    sys.exit(app.exec_())

Upvotes: 0

Views: 1216

Answers (2)

musicamante
musicamante

Reputation: 48335

Drawing on a raster image means overriding its contents, there's no "erase" nor "undo": it's like using a brush on a painting: if you try to "erase" it's like using bleach on what you're trying to "unpaint".

Keep track of what you're manually painting (the coordinates) and then implement the paintEvent accordingly.

class Target(QWidget):

    def __init__(self):
        super().__init__()
        self.drawing = False
        self.image = QPixmap(r"Pictures\target_png_300.png")
        self.setGeometry(0, 0, 300, 300)
        self.resize(self.image.width(), self.image.height())
        self.points = []
        self.show()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(self.rect(), self.image)
        r = QRect(-1, -1, 2, 2)
        painter.setWindow(r)
        painter.setPen(QPen(Qt.black, 0.06, Qt.DotLine, Qt.RoundCap))
        for point in self.points:
            painter.drawPoint(point)
    
    def paintCoordinate(self, x, y):
        self.points.append(QPointF(x, y))
        self.update()

    def deleteLastPoint(self):
        self.points.pop()
        self.update()


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    ex = Target()
    ex.paintCoordinate(0, 0)
    ex.paintCoordinate(0.5, 0.5)
    QTimer.singleShot(1000, lambda: ex.deleteLastPoint())
    sys.exit(app.exec_())

Upvotes: 0

eyllanesc
eyllanesc

Reputation: 244033

If you want only one point then don't modify the QPixmap but just do the painting in the paintEvent method:

class Target(QWidget):
    def __init__(self):
        super().__init__()
        self._pixmap = QPixmap()
        self._coordinate = QPointF()

    @property
    def pixmap(self):
        return self._pixmap

    @pixmap.setter
    def pixmap(self, pixmap):
        self._pixmap = pixmap.copy()
        self.update()
        size = self.pixmap.size()
        if size.isValid():
            self.resize(size)
        else:
            self.resize(300, 300)

    @property
    def coordinate(self):
        return self._coordinate

    @coordinate.setter
    def coordinate(self, point):
        self._coordinate = point
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(self.rect(), self.pixmap)
        r = QRect(-1, -1, 2, 2)
        painter.setWindow(r)
        pen = QPen(Qt.black, 0.06, Qt.DotLine, Qt.RoundCap)
        painter.setPen(pen)
        painter.drawPoint(self.coordinate)


if __name__ == "__main__":

    app = QApplication(sys.argv)
    ex = Target()
    ex.pixmap = QPixmap(r"Pictures\target_png_300.png")
    ex.coordinate = QPointF(0, 0)
    ex.coordinate = QPointF(0.5, 0.5)
    ex.show()
    sys.exit(app.exec_())

Upvotes: 1

Related Questions