vtk数据交互的两种方式之回调函数、vtkCommand

参考博客: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)
  • obj是调用事件的对象(即调用AddObserver()函数的主题对象,例如interactor);
  • eid为所要监听的事件ID,VTK中的事件定义在vtkCommand.h文件中;
  • clientdata是与vtkCalbackCommand实例相关的数据。简单说,是指回调函数里需要访问主程序里的数据时,由主程序向回调函数传递的数据,可以通过vtkCallbackCommand::SetClientData()函数设置。
  • calldata是执行vtkObject::InvokeEvent()函数时,随着回调函数发送的数据,比如当调用ProgressEvent事件时,会自动发送当前的进度值作为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事件的处理过程,实现所需的交互。

你可能感兴趣的:(vtk,交互)