Reputation: 13
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.
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
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
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