ITK/VTK图像处理过程普遍耗时,所以设置进度条监听事件进度是一个很好的选择。在ITK和VTK中使用观察者/命令模式来监听任务的进度事件(ProgressEvent)。关于观测者/命令模式见之前一篇博文(VTK交互)。在使用addObserver()确定了所监听的事件后。最主要的是实现事件响应函数。下面分别记录ITK和VTK事件响应。
VTK
VTK中事件响应可以通过两种方式实现,1 编写回调函数 2编写VTKCommand的子类
1 回调函数签名:
void func(vtkObject* obj,unsigned long eid,void* clientdata,void *calldata) 重点后两个参数: clientdata: 客户数据 这个可以传递主程序的数据对象 比如:进度对话框对象 calldata: 回调函数发出数据 比如:ProgressEvent事件,会自动发送进度值作为calldata回到函数的使用:要先实例化一个vtkCallBackCommand类,然后调用该类的setCallback()函数添加回掉函数
2 继承VTKCommand类
class CommandProgressUpdate : public vtkCommand { public: void setDialog(QProgressDialog* Dialog) { if(Dialog==NULL) { ProgressDialog=NULL; return; } ProgressDialog=Dialog; } vtkStandardNewMacro(CommandProgressUpdate); public: virtual void Execute(vtkObject*caller,unsigned long eventId,void* callData)
{ ProgressDialog->setvalue((double*)callData); } private: QProgressDialog *ProgressDialog=NULL;
Execute函数在监听事件发生后会自动被类vtkCommand调用
ITK
itk与vtk略有不同,首先其没有CallBackCommand类 这就意味不能通过编写回掉函数形式实现事件响应。 但itk有itkCommand类 所以我们可以通过继承该类实现事件响应。从ITK官方文档找到几个例子如下:
class MyCommand : public itk::Command { public: itkNewMacro( MyCommand ); public: void Execute(itk::Object *caller, const itk::EventObject & event) { Execute( (const itk::Object *)caller, event); } void Execute(const itk::Object * object, const itk::EventObject & event) { std::cout << "Command called." << std::endl; } };在参考文献1中给出了一个更加详尽的例子说明如何实现进度监听
ITK/VTK管线中断:调用函数
SetAbortGenerateData(true)
参考文献:
【1】获取进度的事件响应