Reputation: 141
I'm getting started with vtk (6) in python and have a problem handling KeyPressEvent. I want to subclass the vtkInteractorStyleTrackballCamera
if I use this pattern, my interactor style does not have getKeySym() and I can't decode what key was pressed
class KeyPressInteractorStyle(vtk.vtkInteractorStyleTrackballCamera):
def __init__(self,parent=None):
self.AddObserver("MiddleButtonPressEvent",self.middleButtonPressEvent)
self.AddObserver("MiddleButtonReleaseEvent",self.middleButtonReleaseEvent)
self.AddObserver("KeyPressEvent",self.keyPress)
def keyPress(self,obj,event):
key = obj.GetKeySym() #Does not work
print("key %s" % key)
return
def middleButtonPressEvent(self,obj,event):
...
return
def middleButtonReleaseEvent(self,obj,event):
...
return
However if I use the factory vtkInteractorStyleTrackballCamera class and add observers with this pattern, the same keyPress() is able to access GetKeySym().
def KeyPress(obj,event):
key = obj.GetKeySym() #works fine
print("key %s" % key)
def MiddleButtonPressEvent(obj,event):
...
return
def MiddleButtonReleaseEvent(obj,event):
...
return
...
interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
interactor.AddObserver("KeyPressEvent",KeyPress)
interactor.AddObserver("MiddleButtonPressEvent",MiddleButtonPressEvent)
interactor.AddObserver("MiddleButtonReleaseEvent",MiddleButtonReleaseEvent)
I'm a newbie, what should I do to get functionality in my class?
Upvotes: 2
Views: 5714
Reputation: 314
This worked for me with vtk 9.2.0:
class KeyPressStyle(vtk.vtkInteractorStyleTrackballCamera):
def __init__(self):
super().__init__()
self.AddObserver("KeyPressEvent", self.OnKeyPress)
def OnKeyPress(self, obj, event):
print(f"Key {obj.GetInteractor().GetKeySym()} pressed")
def main():
ren1 = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren1)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
renWin.Render()
iren.SetInteractorStyle(vtk.KeyPressStyle())
Upvotes: 1
Reputation: 361
I found this question by googling "vtk keypressevent python" and just wanted to share my solution as there is no need for subclassing vtkInteractorStyle
:
def keypress_callback(obj, ev):
key = obj.GetKeySym()
print(key, 'was pressed')
render_interactor = vtk.vtkRenderWindowInteractor()
render_interactor.AddObserver('KeyPressEvent', keypress_callback, 1.0)
Upvotes: 1
Reputation: 36
If you are making an Interactor Style class I think it's safe to assume it will be applied to an interactor as some point. I noticed in your solution you set the parent to be a vtk.vtkRenderWindowInteractor(). It would be better to set the parent to be the specific instance of vtkRenderWindowInteractor:
class MyInteractorStyle(vtk.vtkInteractorStyleTrackballCamera):
def __init__(self,parent=None):
self.parent = iren
self.AddObserver("KeyPressEvent",self.keyPressEvent)
def keyPressEvent(self,obj,event):
key = self.parent.GetKeySym()
if key == 'l':
print(key)
return
...
iren = vtk.vtkRenderWindowInteractor()
iren.SetInteractorStyle(MyInteractorStyle())
iren.SetRenderWindow(renWin)
renWin.Render()
iren.Initialize()
iren.Start()
Upvotes: 2
Reputation: 141
Right I found a solution after checking the vtk doxygen for and seeing that vtkInteractorStyleTrackballCamera does not inherit from vtkRenderWindowInteractor which I had assumed in the example I was porting. I decided to pass my style class a parent so that it could access the RenderWindow GetKeySym(). It may not be the best solution, but here's how as an FYI:
class KeyPressInteractorStyle(vtk.vtkInteractorStyleTrackballCamera):
def __init__(self,parent=None):
self.parent = vtk.vtkRenderWindowInteractor()
if(parent is not None):
self.parent = parent
self.AddObserver("KeyPressEvent",self.keyPress)
def keyPress(self,obj,event):
key = self.parent.GetKeySym()
...
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetInteractorStyle(KeyPressInteractorStyle(parent = interactor))
Upvotes: 1