Consume a VTK event in Python

Hi all,

If I press s or w in a vtkRenderWindow a KeyPress event is fired and the representation of the rendered objects changes to surface or wireframe. The event observer, I should think, is handled by the vtkRenderWindowInteractor.

I would like to add an observer that would consume the event and stop any further processing of the event in Python.

I googled and found that I should use SetAbortFlag but from a couple of (old) links I gather that this is not possible in Python:
https://vtk.org/pipermail/vtk-developers/2007-September/020213.html
https://vtk.org/Wiki/VTK/Python_Wrapper_Enhancement#Wrap_vtkCommand_and_allow_it_to_be_subclassed

Given that the links I could find are old, is this still impossible?
How could I achieve this otherwise?

Thanks

Edo

PS I have an example where I tried to do some experiments

Cc: @spyridon97 @dgobbi

After further investigation I managed by

  1. adding an observer on CharEvent with higher priority than the one that is in the interactor. Earlier I used KeyPressEvent which was not correct.
  2. modifying the key code of the event. I set it to no character to be absolutely sure
def consumeCharEvent(interactor, event):
    if interactor.GetKeyCode() in ['s', 'w']:
        interactor.SetKeyCode("")

iren = vtk.vtkRenderWindowInteractor()
iren.AddObserver("CharEvent", consumeCharEvent, 10)

To make it a clean job I would like to be able to get the priority of the CharEvent observer I want to override. I do not seem to find a way to get any observers from a vtkObject, but printing the object (the interactor) I can find the observer priority and tag.

vtkObserver (000001F012EB9910)
        Event: 22
        EventName: CharEvent
        Command: 000001F012ECA480
        Priority: 0
        Tag: 81

Any help is welcome

Edo

The default handling of the event is done in vtkInteractorStyle and the representation switch is done in the OnChar method.

I haven’t found any way to get an observer from an object.
The following function reads the string representation of the object and returns the priority.

def GetObserverPriority(vtk_object, event_name: str) -> int:
    '''Given a vtk object and an event name, return the priority of the observer
    
    It is impossible to get an observer from the object programmatically, but
    the string representation of the object contains the observers with priority.

    This code reads the string representation and returns the priority as integer.
    '''
    string = str(vtk_object)

    ss = string.split("vtkObserver")

    eventObservers = []
    for s in ss:
        lines = s.split("\n")
        eo = {}
        for line in lines:
            try:
                k,v = line.split(":")
                k = k.strip()
                v = v.strip()
                if k in ['Event', 'EventName', 'Command', 'Priority', 'Tag']:
                    eo[k] = v
                    eventObservers.append(eo)
            except:
                pass

    for el in eventObservers:
        if el['EventName'] == event_name:
            return int(el['Priority'])

Hope this helps

Edo