参考博客:VTK交互之vtkCommand_阿兵-AI医疗的博客-CSDN博客_vtkcommand
一、观察者/命令模式
VTK中用的较多的设计模式是:观察者/命令模式(Observer/Command)。
要实现数据交互,主要基于观察者/命令模式,可以通过两种方式来实现:一种是回调函数;另外一种是从vtkCommand中派生出子类。两者基本类似,通过AddObserver监视事件,然后调用事件回调函数或者在vtkCommand::Execute()中实现功能。
二、事件回调函数
1、AddObserver中对某个事件添加观察者到VTK中,当这个事件一旦被触发,就会自动调用回调函数或者执行相关操作
unsigned long AddObserver(unsigned long event, vtkCommand *, float priority = 0.0f);
unsigned long AddObserver(const char* event, vtkCommand *, float priority = 0.0f);
2、vtk中使用回调函数执行步骤主要是以下三步:
(1)定义回调函数(如下的fun函数)
void func(vtkObject* obj, unsigned long eid, void* clientdata, void* calldata)
(2)创建一个vtkCallbackCommand对象,并调用vtkCallbackCommand::SetCallback()函数设置所定义的回调函数。
vtkSmartPointer mouseCallback = vtkSmartPointer::New();
mouseCallback->SetCallback(MyCallbackFunc);
(3)将vtkCallbackCommand对象添加到对象的观察者列表中
interactor->AddObserver(vtkCommand::LeftButtonPressEvent, mouseCallback);
vtkRenderWindowInteractor提供了一种独立于平台的交互机制,用来响应不同平台的鼠标、按键和时钟等消息。如当vtkRenderWindowInteractor来监听鼠标左键按下消息,一旦监听到对象的观察者列表中的消息时,程序就会自动调用事件的回调函数。
三、vtkCommand子类
实现vtkCommand子类同样也需要以下三个步骤:
1、从vtkCommand派生出子类,并实现vtkCommand::Execute()函数,该函数原型是
virtual void Exeute(vtkObject* caller, unsigned long eventId, void* callData) = 0;
Execute()是纯虚函数,所以从vtkCommand派生的类都必须实现这个方法。
2、在主程序中实例化一个vtkCommand子类的对象以及调用相关的方法。
3、调用AddObserver()函数监听感兴趣的事件。
补充:
除了基于的观察者/命令模式外,还有一种方式交互器样式,来实现,在VTK程序中,当实例化交互器样式vtkRenderWindowInteractor对象时,程序运行时会根据具体的平台实例化对应的子类来响应窗口消息,VTK内部通过vtkObject::InvokeEvent()函数将平台相关的消息翻译成VTK事件,最后再分发给不同的观察者,而观察者则调用回调函数vtkInteractorStyle::ProcessEvents()具体来处理这些VTK事件,因此,也可以从vtkInteractorStyle或其子类中派生出子类,在所派生的子类里定制这些VTK事件的处理过程,实现所需的交互。