Skip to main content
1 of 3

How to draw virtual dotted line using PyQgis?

I am developing a plugin in QGIS3.14 to customize editing. I am drawing a line by clicking on map canvas. It is showing points with mouse click and creating a line with right click. I want to trace mouse by showing dotted line while generating points. Just like existing 'Add Line Feature' function of 'Toggle Editing' in QGIS. Following is the code which I am using now.

class StraightLine(QgsMapToolEmitPoint):
points=[]
def __init__(self, canvas):
    # call the parent constructor
    QgsMapToolEmitPoint.__init__(self, canvas)
    # store the passed canvas
    self.canvas = canvas

    # flag to know whether the tool is performing a drawing operation 
    self.isDrawing = False
    self.dlg = CurveToolDialog()
    # create and setup the rubber band to display the line
    self.rubberBand = QgsRubberBand(iface.mapCanvas(), QgsWkbTypes.LineGeometry)  
    self.rubberBand.setColor( Qt.red )
    self.rubberBand.setWidth( 1 )
    self.dlg.setFocusPolicy(Qt.StrongFocus) 

def clear(self):
    self.rubberBand.reset( False )    # False = not a polygon = a line

def delete(self):
    self.canvas.scene().removeItem( self.rubberBand )

def canvasPressEvent(self, e):
    # which the mouse button?
    if e.button() == Qt.LeftButton:
        # left click

        # if it's the first left click, clear the rubberband 
        if not self.isDrawing:
            self.clear()
            self.points=[]
        # we are drawing now
        self.isDrawing = True
        point = self.toMapCoordinates( e.pos() )
        # add a new point to the rubber band
        self.rubberBand.addPoint( point, True )    # True = display updates on the canvas
        self.points.append(QgsPoint(point))
        polyline = QgsGeometry.fromPolyline(self.points)
        feat = QgsFeature()
        feat.setGeometry(polyline)            
        self.rubberBand.setToGeometry(polyline)
        self.rubberBand.movePoint( point )
        self.rubberBand.show()
        # and finally show the rubber band
        self.rubberBand.show()
        
    if e.button() == Qt.RightButton:
        
        # right click, stop drawing
        self.isDrawing = False
        # emit a signal
        polyline = QgsGeometry.fromPolyline(self.points)
        feat = QgsFeature()
        feat.setGeometry(polyline)            
        self.rubberBand.setToGeometry(polyline)
        self.rubberBand.show()  
        layer=iface.activeLayer()
        f=layer.getFeature(0)
        prov1 = layer.dataProvider()
        layer.startEditing()
        prov1.addFeatures([feat])
        feat.setAttributes(f.attributes())
        layer.commitChanges()
        layer.updateExtents()
        iface.mapCanvas().refresh()  
        self.dlg.open()
       
def geometry(self):
    return self.rubberBand.asGeometry() 

I tried adding following function which uses painter, but it doesn't make any change in working of the tool.

def mouseMoveEvent(self, event):
    if self.last:
        self.painter.drawLine(self.last, event.pos())
        self.last = event.pos()
        self.update()