如何使用 python 在 vtk KeyPressEvent 中获取键码

How to get the key code in a vtk KeyPressEvent using python

我在 python 中开始使用 vtk (6),但在处理 KeyPressEvent 时遇到问题。我想子class vtkInteractorStyleTrackballCamera

如果我使用此模式,我的交互器样式没有 getKeySym() 并且我无法解码按下的键

    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

但是,如果我使用工厂 vtkInteractorStyleTrackballCamera class 并使用此模式添加观察者,则相同的 keyPress() 能够访问 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)

我是新手,我应该怎么做才能在 class 中获得功能?

是的,在检查 vtk doxygen 并看到 vtkInteractorStyleTrackballCamera does not inherit from vtkRenderWindowInteractor which I had assumed in the example 我正在移植后,我找到了解决方案。我决定将我的样式 class 传递给父级,以便它可以访问 RenderWindow GetKeySym()。它可能不是最好的解决方案,但仅供参考:

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))

如果您正在制作交互器样式 class 我认为可以安全地假设它将作为某个点应用于交互器。我注意到在您的解决方案中,您将父级设置为 vtk.vtkRenderWindowInteractor()。最好将父级设置为 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()

我通过谷歌搜索 "vtk keypressevent python" 发现了这个问题,只是想分享我的解决方案,因为不需要子类化 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)