Skip to main content
added 4 characters in body
Source Link
Kalak
  • 4k
  • 12
  • 28
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
        ifelif event.type() == QEvent.HoverEnter:
            self.hoverEnter.emit()
            return True
        ifelif 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)
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)
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
        elif event.type() == QEvent.HoverEnter:
            self.hoverEnter.emit()
            return True
        elif 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)
added 176 characters in body
Source Link
Kalak
  • 4k
  • 12
  • 28

PS: The reason for not using the built-in QgsFocusWatcher is that, with focus, you need to click somewhere outside the map canvas instead of just moving your mouse cursor.

PS: The reason for not using the built-in QgsFocusWatcher is that, with focus, you need to click somewhere outside the map canvas instead of just moving your mouse cursor.

Source Link
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)