I have a scene where I would like to draw a line between two points(mouse press should be the start point and mouse release as the endpoint) using the QPainterpath.
Here is a demonstration of how I want it to be.
Here is what’s happening with my current code.
Below is the code I have tried
import sys from PyQt5 import QtWidgets, QtCore, QtGui class Scene(QtWidgets.QGraphicsScene): def __init__(self, *args, **kwargs): super(Scene, self).__init__(*args, **kwargs) self.point = QtCore.QPointF(0.0, 0.0) self.path = QtGui.QPainterPath() self.start_point = None self.end_point = None self.start = False def mousePressEvent(self, event): self.start_point = event.scenePos() self.start = True self.path = QtGui.QPainterPath(self.start_point) # self.addLine(self.line.setP1(self.start_point)) super().mousePressEvent(event) def mouseMoveEvent(self, event): if self.start: self.path.lineTo(event.scenePos()) # self.path.moveTo(event.scenePos()) self.addPath(self.path, QtGui.QPen(QtCore.Qt.red)) super(Scene, self).mouseMoveEvent(event) def mouseReleaseEvent(self, event): if self.start: print(self.path) self.path.lineTo(event.scenePos()) # self.path.moveTo(event.scenePos()) self.addPath(self.path, QtGui.QPen(QtCore.Qt.red)) self.start = False super(Scene, self).mouseReleaseEvent(event) def main(): app = QtWidgets.QApplication(sys.argv) view = QtWidgets.QGraphicsView() view.setRenderHint(QtGui.QPainter.Antialiasing) view.setMouseTracking(True) scene = Scene() view.setScene(scene) view.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
Advertisement
Answer
Every time lineTo is used then a new line is created where the starting point is the last point added and the end point is the one that is passed to the function, so you see the curves since they are the union of those lines. The solution is to have 2 variables that store the start point and the end point, and be updated when necessary, then use that information to update the QGraphicsPathItem, not the QPainterPath. The same concept can be applied for QGraphicsLineItem with QLineF.
class Scene(QtWidgets.QGraphicsScene): def __init__(self, *args, **kwargs): super(Scene, self).__init__(*args, **kwargs) self.path_item = self.addPath(QtGui.QPainterPath()) self.start_point = QtCore.QPointF() self.end_point = QtCore.QPointF() def mousePressEvent(self, event): self.start_point = event.scenePos() self.end_point = self.start_point self.update_path() super().mousePressEvent(event) def mouseMoveEvent(self, event): if event.buttons() & QtCore.Qt.LeftButton: self.end_point = event.scenePos() self.update_path() super(Scene, self).mouseMoveEvent(event) def mouseReleaseEvent(self, event): self.end_point = event.scenePos() self.update_path() super(Scene, self).mouseReleaseEvent(event) def update_path(self): if not self.start_point.isNull() and not self.end_point.isNull(): path = QtGui.QPainterPath() path.moveTo(self.start_point) path.lineTo(self.end_point) self.path_item.setPath(path)