I am creating a plugin with a preview window where the user must select a rectangle to define the study zone.

I see in this https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/canvas.html the Writing Custom Map Tools example but I do not know how to call it and give the possibility to the user to draw the rectangle.

I put this code in the .ui dialog python script:

class RectangleMapTool(QgsMapToolEmitPoint):
    def __init__(self, canvas):
        self.canvas = canvas
        QgsMapToolEmitPoint.__init__(self, self.canvas)
        self.rubberBand = QgsRubberBand(self.canvas, True)

    def reset(self):
        self.startPoint = self.endPoint = None
        self.isEmittingPoint = False

    def canvasPressEvent(self, e):
        self.startPoint = self.toMapCoordinates(e.pos())
        self.endPoint = self.startPoint
        self.isEmittingPoint = True
        self.showRect(self.startPoint, self.endPoint)

    def canvasReleaseEvent(self, e):
        self.isEmittingPoint = False
        r = self.rectangle()
        if r is not None:
          print("Rectangle:", r.xMinimum(),
                r.yMinimum(), r.xMaximum(), r.yMaximum()

    def canvasMoveEvent(self, e):
        if not self.isEmittingPoint:

        self.endPoint = self.toMapCoordinates(e.pos())
        self.showRect(self.startPoint, self.endPoint)

    def showRect(self, startPoint, endPoint):
        if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():

        point1 = QgsPoint(startPoint.x(), startPoint.y())
        point2 = QgsPoint(startPoint.x(), endPoint.y())
        point3 = QgsPoint(endPoint.x(), endPoint.y())
        point4 = QgsPoint(endPoint.x(), startPoint.y())

        self.rubberBand.addPoint(point1, False)
        self.rubberBand.addPoint(point2, False)
        self.rubberBand.addPoint(point3, False)
        self.rubberBand.addPoint(point4, True)    # true to update canvas

    def rectangle(self):
        if self.startPoint is None or self.endPoint is None:
          return None
        elif (self.startPoint.x() == self.endPoint.x() or \
              self.startPoint.y() == self.endPoint.y()):
          return None

          return QgsRectangle(self.startPoint, self.endPoint)

    def deactivate(self):

1 Answer 1


You need to call your RectangleMapTool constructor somewhere in the plugin code and then set it as the current map tool for the canvas like this:

rectangleTool = RectangleMapTool(self.iface.mapCanvas())

If you also want to perform some action after the rectangle is drawn then you should implement a PyQt signal in RectangleMapTool.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.