Skip to main content
1 of 3
Kalak
  • 4k
  • 12
  • 28

I don't think this can be done without an eventFilter function (afaik).

If you are ok with eventFilter then this solution will work using a QEvent.HoverLeave detector, built like QgsFocusWatcher.

enter image description here

class QgsHoverWatcher(QObject):
    hoverEnter = pyqtSignal()
    hoverLeave = pyqtSignal()
    
    def __init__(self, parent):
        QObject.__init__(self)
        self._parent = parent
        self._parent.installEventFilter(self)

    def eventFilter(self, object, event):
        if not (object is self._parent):
            return False
        if event.type() == QEvent.HoverEnter:
            self.hoverEnter.emit()
            return True
        if event.type() == QEvent.HoverLeave:
            self.hoverLeave.emit()
            return True
        else:
            return False

    def __del__(self):
        while True:
            try:
                self.hoverEnter.disconnect()
            except TypeError:
                break
        while True:
            try:
                self.hoverLeave.disconnect()
            except TypeError:
                break
        self._parent.removeEventFilter(self)
        
        
class CircleMapTool(QgsMapToolEmitPoint):
    def __init__(self, canvas):
        QgsMapToolEmitPoint.__init__(self, canvas)
        self.rubber_band = QgsRubberBand(canvas, QgsWkbTypes.PointGeometry)
        self.rubber_band.setColor(Qt.red)
        self.rubber_band.setWidth(20)
        
        self.canvas_hover_watcher = QgsHoverWatcher(canvas)
        self.canvas_hover_watcher.hoverLeave.connect(self.reset)

    def reset(self):
        self.rubber_band.reset(QgsWkbTypes.PointGeometry)

    def canvasMoveEvent(self, e):
        point = self.toMapCoordinates(e.pos())
        if self.rubber_band.size() == 0:
            self.rubber_band.addPoint(point)
        else:
            self.rubber_band.movePoint(point)

    def deactivate(self):
        self.reset()
        self.canvas_hover_watcher.__del__()
        QgsMapTool.deactivate(self)

tool = CircleMapTool(iface.mapCanvas())
iface.mapCanvas().setMapTool(tool)
Kalak
  • 4k
  • 12
  • 28