您的位置:首页 > 其它

VTK交互

2016-04-29 16:13 197 查看
   说到VTK交互,马上会想到的就是vtkRenderWindowInterator。他是VTK的交互类 可以响应各种的鼠标/键盘/时钟等消息事件。今天阅读了大量资料,关于如何给交互器增加或更改交互事件。在这里梳理一下,给以后做个参考。 在一篇VTK官方文档翻译中 看到大的方向先分为两大类(参考文献1):VTK两种不同的方法控制交互:(1)使用vtkInteractStyle的子类 (2)添加Observer监听vtkRenderWindowInterator里的事件

  先说第二种方法,就是使用了VTK中的观察者/命令模式。类vtkObject有如下函数:

unsigned long AddObserver(unsigned long event, vtkCommand *, float priority=0.0f);
unsigned long AddObserver(const char *event, vtkCommand *,float priority=0.0f);
该函数可以针对某个事件添加观察者到VtK对象中。  也就是说在VTK对象中维护一个观察者列表 一个观察者负责监听一个VTK事件并与之对应一个vtkCommand对象(该对象中添加了相应的回调函数)  添加多个观察者我们就可以监听多个对象  这个有些类似Qt的信号槽机制(在后面介绍vtkEventQtSlotConnect中就可以看到其相似处)。

关于观察者/命令模式中的事件响应函数实现方式有两种:使用事件回掉函数或者vtkCommand派生出子类 (VTK图形图像进阶P194)

第一种方法:了解一下交互器响应事件的 一般流程 首先由系统窗口捕捉事件 再由InvokeEvent()函数翻译成VTK事件。然后将该事件路由到vtkInteractorObserver及其子类,在由已经对该事件进行注册的vtkinteratorObserver或其子类进行具体的相应操作。  而我们说的vtkInteractStyle正是vtkinteratorObserver的子类。 可见vtkInteractStyle是一个观察者类。它单独维护一个观察者列表
并响应自己定义的的事件 vtkInteractStyle的响应函数都是纯虚函数 所以我们不能直接使用vtkInteractStyle  而是使用其子类 例如vtkinteractStyleImage 一般我们都会使用setinteractoStyle为交互器添加一个交互器样式  这样就扩展了交互器的交互能力。注意:交互器样式只是监测自己内部注册的消息事件 不会去检测交互器注册的事件。  例如:LevelWindowEvent 这是改变窗位窗宽的事件 

而在vtkRenderWindowInterator是没有该事件的。

    vtkRenderWindowInterator中的事件(参考文献2):

Events:
vtkCommand::RightButtonPressEvent vtkCommand::EnterEvent vtkCommand::MiddleButtonReleaseEvent vtkCommand::CharEvent vtkCommand::ExitEvent vtkCommand::LeftButtonPressEvent vtkCommand::UserEvent vtkCommand::ConfigureEvent vtkCommand::LeftButtonReleaseEvent vtkCommand::EndPickEvent vtkCommand::KeyReleaseEvent vtkCommand::ExposeEvent vtkCommand::MiddleButtonPressEvent vtkCommand::StartEvent vtkCommand::LeaveEvent vtkCommand::KeyPressEvent vtkCommand::RenderEvent vtkCommand::MouseWheelForwardEvent vtkCommand::MouseWheelBackwardEvent vtkCommand::RightButtonReleaseEvent vtkCommand::MouseMoveEvent vtkCommand::StartPickEvent
所以vtkRenderWindowInterator不能响应该事件 而在vtkinteractStyleImage中有该相应事件 所以就可以。

vtkinteractStyleImage中的事件(参考文献3):

Events:
vtkCommand::StartPickEvent vtkCommand::ResetWindowLevelEvent vtkCommand::WindowLevelEvent vtkCommand::EndPickEvent vtkCommand::StartWindowLevelEvent vtkCommand::EndWindowLevelEvent vtkCommand::PickEvent vtkCommand::InteractionEvent


最后说一个vtkEventQtSlotConnect类 该类实现了vtk事件和槽函数的连接。vtk事件扮演了Qt中的信号角色。该类中有一个connect函数 说明如下:

virtual void Connect (vtkObject *vtk_obj, unsigned long event, const QObject *qt_obj, const char *slot, void *client_data=NULL, float priority=0.0, Qt::ConnectionType type=Qt::AutoConnection)

最主要前四个参数:1 消息事件的拥有者

                                    2 消息事件

                                    3 槽函数拥有者

                                    4槽函数

注:就像前面一直强调的 第一个参数一定是消息事件的拥有者 否则就不能触发事件 也就不能响应后面的槽函数

   例如; LevelWindowEvent事件 如果第一个参数你给出vtkRenderWindowInterator而不是vtkinteractStyleImage 就不会响应 即使交互器已经添加了该交互样式也不可以 因为该事件并没有直接在交互器中注册

参考文献:

  【1】VTK交互

  【2】vtkRenderWindowInterator

  【3】vtkInteractorStyleImage
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: