rdbrn
(Ruben de Bruin)
1
I use vtk in an application (qt) where I would like to define my own events for right-mouse button (context menu) as well as some of the key presses.
Problem is that they are already used by the interactor.
(https://vtk.org/doc/nightly/html/classvtkInteractorStyle.html#details) Is there a way to keep the interactor from handling these events?
I’m using python so subclassing the interactor (like sugested here: Selectively disable and enable default mouse interactions in vtk) is not an option.
Is there any other way to disable some of the default interactions?
dgobbi
(David Gobbi)
2
You can override the interaction in the vtkInteractorStyle classes.
First, choose a vtkInteractorStyle that most closely matches your desired behavior, e.g. vtkInteractorStyleTrackball or vtkInteractorStyleUser.
Then, add Python observers to the events you want to override or disable:
style.AddObserver("KeyPressEvent", callback)
style.AddObserver("KeyReleaseEvent", callback)
style.AddObserver("CharEvent", callback)
rdbrn
(Ruben de Bruin)
3
Hi @dgobbi , yes that’s what I thought I was doing but it didn’t work.
I now realize that I need to add the oberservers to the STYLE and not to the renderWindowInteractor (which is what I was doing).
Thanks!
Posting a full example here for the next person running into this:
vtkInteractorStyleTrackballCamera with keys and right button features disabled.
import vtk
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkFiltersSources import vtkCylinderSource
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkPolyDataMapper,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer
)
def main():
colors = vtkNamedColors()
# Create a sphere
cylinderSource = vtkCylinderSource()
cylinderSource.SetCenter(0.0, 0.0, 0.0)
cylinderSource.SetRadius(5.0)
cylinderSource.SetHeight(7.0)
cylinderSource.SetResolution(100)
# Create a mapper and actor
mapper = vtkPolyDataMapper()
mapper.SetInputConnection(cylinderSource.GetOutputPort())
actor = vtkActor()
actor.GetProperty().SetColor(colors.GetColor3d('Cornsilk'))
actor.SetMapper(mapper)
# Create a renderer, render window, and interactor
renderer = vtkRenderer()
renderWindow = vtkRenderWindow()
renderWindow.SetWindowName('Cylinder')
renderWindow.AddRenderer(renderer)
style = vtk.vtkInteractorStyleTrackballCamera()
style.AddObserver("CharEvent", lambda x, y: print('key char'))
style.AddObserver("RightButtonPressEvent", lambda x, y: print('right press'))
style.AddObserver("RightButtonReleaseEvent", lambda x, y: print('right release'))
renderWindowInteractor = vtkRenderWindowInteractor()
renderWindowInteractor.SetInteractorStyle(style)
renderWindowInteractor.SetRenderWindow(renderWindow)
# Add the actor to the scene
renderer.AddActor(actor)
renderer.SetBackground(colors.GetColor3d('DarkGreen'))
# Render and interact
renderWindow.Render()
renderWindowInteractor.Start()
if __name__ == '__main__':
main()