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
.
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)