@@ -316,6 +316,20 @@ def __repr__(self):
316316 return "<GestureMatch: %s:%s>" % (type_str , state_str )
317317
318318
319+ class WheelEventMatch (EventMatch ):
320+ """A callable returning True if it matches a wheel event"""
321+
322+ def __init__ (self , modifiers = QC .Qt .KeyboardModifier .NoModifier ):
323+ super ().__init__ ()
324+ self .modifiers = modifiers
325+
326+ def get_event_types (self ):
327+ return frozenset ((QC .QEvent .Type .Wheel ,))
328+
329+ def __call__ (self , event : QC .QEvent ):
330+ return isinstance (event , QG .QWheelEvent ) and event .modifiers () == self .modifiers
331+
332+
319333# Finite state machine for event handling ----------
320334class StatefulEventFilter (QC .QObject ):
321335 """Gestion d'une machine d'état pour les événements
@@ -434,6 +448,10 @@ def gesture(self, kind, state):
434448 ("gesture" , kind , state ), GestureEventMatch (kind , state )
435449 )
436450
451+ def wheel (self , modifiers = QC .Qt .KeyboardModifier .NoModifier ):
452+ """Création d'un filtre pour l'événement molette"""
453+ return self .events .setdefault (("wheel" , modifiers ), WheelEventMatch (modifiers ))
454+
437455 def nothing (self , filter , event ):
438456 """A nothing filter, provided to help removing duplicate handlers"""
439457 pass
@@ -847,6 +865,73 @@ def click(self, filter, event):
847865 menu .popup (event .globalPos ())
848866
849867
868+ class WheelHandler (QC .QObject ):
869+ def __init__ (
870+ self ,
871+ filter : StatefulEventFilter ,
872+ mods = QC .Qt .KeyboardModifier .NoModifier ,
873+ start_state = 0 ,
874+ ):
875+ super ().__init__ ()
876+ self .state0 = filter .add_event (
877+ start_state , filter .wheel (mods ), self .wheel , start_state
878+ )
879+
880+ def wheel (self , filter : StatefulEventFilter , event : QG .QWheelEvent ):
881+ """
882+
883+ :param filter:
884+ :param event:
885+ """
886+ raise NotImplementedError ()
887+
888+
889+ class WheelZoomHandler (WheelHandler ):
890+ def get_zoom_param (
891+ self , plot : BasePlot , pos : QPoint , factor : float
892+ ) -> tuple [tuple [float , float , float , float ], tuple [float , float , float , float ]]:
893+ """Returns the parameters to use for zooming on the plot.
894+
895+ Args:
896+ plot: instance of BasePlot to use as a reference.
897+ pos: position on the plot canvas of the current hotspot.
898+ factor: factor by which to zoom.
899+
900+ Returns:
901+ Returns two tuples of four floats each, representing the parameters used
902+ by BasePlot.do_zoom_view.
903+ """
904+ rect_width = plot .contentsRect ().width ()
905+ dx = (
906+ pos .x () * factor ,
907+ pos .x (),
908+ pos .x (),
909+ rect_width ,
910+ )
911+ dy = (
912+ pos .y () * factor ,
913+ pos .y (),
914+ pos .y (),
915+ rect_width ,
916+ )
917+ return dx , dy
918+
919+ def wheel (self , filter : StatefulEventFilter , event : QG .QWheelEvent ):
920+ """
921+
922+ :param filter:
923+ :param event:
924+ """
925+ plot = filter .plot
926+ delta = event .angleDelta ().y () / 360
927+
928+ center_point = event .globalPos ()
929+ center_point = filter .plot .canvas ().mapFromGlobal (center_point )
930+
931+ dx , dy = self .get_zoom_param (plot , center_point , 1 + delta )
932+ plot .do_zoom_view (dx , dy )
933+
934+
850935class QtDragHandler (DragHandler ):
851936 #: Signal emitted by QtDragHandler when starting tracking
852937 SIG_START_TRACKING = QC .Signal (object , "QEvent" )
@@ -1345,18 +1430,25 @@ def stop_moving_action(self, filter, event):
13451430def setup_standard_tool_filter (filter : StatefulEventFilter , start_state ):
13461431 """Création des filtres standard (pan/zoom) sur boutons milieu/droit"""
13471432 # Bouton du milieu
1348- PanHandler (filter , QC .Qt .MidButton , start_state = start_state )
1349- AutoZoomHandler (filter , QC .Qt .MidButton , start_state = start_state )
1433+ PanHandler (filter , QC .Qt .MouseButton . MidButton , start_state = start_state )
1434+ AutoZoomHandler (filter , QC .Qt .MouseButton . MidButton , start_state = start_state )
13501435
13511436 # Bouton droit
1352- ZoomHandler (filter , QC .Qt .RightButton , start_state = start_state )
1353- MenuHandler (filter , QC .Qt .RightButton , start_state = start_state )
1437+ ZoomHandler (filter , QC .Qt .MouseButton . RightButton , start_state = start_state )
1438+ MenuHandler (filter , QC .Qt .MouseButton . RightButton , start_state = start_state )
13541439
13551440 # Gestes
13561441 PinchPanGestureHandler (filter , start_state = start_state )
13571442
13581443 # Autres (touches, move)
13591444 MoveHandler (filter , start_state = start_state )
1360- MoveHandler (filter , start_state = start_state , mods = QC .Qt .ShiftModifier )
1361- MoveHandler (filter , start_state = start_state , mods = QC .Qt .AltModifier )
1445+ MoveHandler (
1446+ filter , start_state = start_state , mods = QC .Qt .KeyboardModifier .ShiftModifier
1447+ )
1448+ MoveHandler (
1449+ filter , start_state = start_state , mods = QC .Qt .KeyboardModifier .AltModifier
1450+ )
1451+ WheelZoomHandler (
1452+ filter , start_state = start_state , mods = QC .Qt .KeyboardModifier .ControlModifier
1453+ )
13621454 return start_state
0 commit comments