Unable to orveride KeyPress events in vtkInteractorStyle?

Hello!!

I’m using VTK 9.1 and Python 3.8 and I’m creating a custom InteractorStyle, derived from vtkInteractorStyleRubberBandPick, where I want to change some of the Events that drive view manipulation etc. to different events to match another application.
I’ve more or less figured out how this should work - BUT, I’m unable to override the default behaviors of the ‘r’ and ‘3’ KeyPressEvents (at least)

By default, ‘r’ invokes the rubber band widgets and ‘3’ invokes stereo mode viewing.

I have added my own KeyPressEvent observer and it correctly calls the command I associated it to - BUT - it ALSO goes on to call the default methods.

So I added a call to remove the existing KeyPressEvent - but it seems to have no effect on behavior…

Code snippet below…

# Define interaction style
class InteractorStyle(vtk.vtkInteractorStyleRubberBandPick):
    def __init__(self, parent = None):
        self.RemoveObservers("KeyPressEvent")
        self.AddObserver("KeyPressEvent",self.OnKeyPress)
        self.AddObserver("MiddleButtonPressEvent",self.OnMMBPressEvent)
        self.camera = None
        self.math = vtk.vtkMath()

    def OnKeyPress(self,obj,event):
        key = self.GetInteractor().GetKeySym()
        self.camera=self.GetDefaultRenderer().GetActiveCamera()
        if key == '1':
            print("\nCamera details...")
            self.print_camera_details()
        elif key == '2':
            self.camera.Roll(30.0)
            print("\nRoll +30...")
            self.print_camera_details()
        elif key == '3':
            self.camera.Pitch(30.0)
            self.camera.OrthogonalizeViewUp()
            print("\nPitch +30...")
            self.print_camera_details()

How do I prevent the default methods from being called?

Thanks,

Doug

The “CharEvent” is what the base class uses for the keyboard. Make sure you add observers for all keyboard events: CharEvent, KeyPressEvent, and KeyReleaseEvent.

Ditto for mouse events, it’s safest to catch them all (press and release) or else the base class might get just the “release” without the press, resulting in state corruption and odd behavior. Your observers can always call OnMiddleButtonDown() and OnMiddleButtonUp() to fallback to the original behavior.

1 Like

@dgobbi Thanks for the CharEvent tip - that helped. I added my own observer and get the behavior I need.

However, I experimented some more with removing Observers (you never know - I might need to do that sometime…) and it just doesn’t seem to change anything.

If I remove KeyPressEvent abd CharEvent Observers, pressing the ‘3’ or ‘r’ keys still invokes the default behaviors

        self.RemoveObservers("KeyPressEvent")
        self.RemoveObservers("CharEvent")

Any idea why?

Doug

When you first create the vtkInteractorStyle, it has no observers. The default behavior is what happens when no observer is present. See the code at this link:

https://gitlab.kitware.com/vtk/vtk/-/blob/v9.0.3/Rendering/Core/vtkInteractorStyle.cxx#L1052

The only way to get rid of the default behavior is to add an observer that overrides the behavior.

Thanks @dgobbi - understood