VTK/Tutorials/Callbacks: Difference between revisions

From KitwarePublic
< VTK‎ | Tutorials
Jump to navigationJump to search
m (Changed the numbering for steps.)
No edit summary
Line 3: Line 3:


To catch these commands, you must do three things:
To catch these commands, you must do three things:
1. Create a function with this signature:
1. Create a function with this signature:
<source lang="cpp">
<source lang="cpp">

Revision as of 11:54, 24 March 2010

Introduction

A callback function is the "observer" in the "command/observer" design pattern. That is, there are times when VTK will know that something has happened and it will send out a command notifying all observers of the event.

To catch these commands, you must do three things:

1. Create a function with this signature: <source lang="cpp">

void func(vtkObject*, unsigned long eid, void* clientdata, void *calldata)

</source>

2. Create a vtkCallbackCommand and set its callback to the function you have just created: <source lang="cpp">

 vtkSmartPointer<vtkCallbackCommand> keypressCallback = 
     vtkSmartPointer<vtkCallbackCommand>::New();
 keypressCallback->SetCallback ( func );

</source>

3. Register the callback that was just created with the object that is observing for the command: <source lang="cpp">

vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =

     vtkSmartPointer<vtkRenderWindowInteractor>::New();
 renderWindowInteractor->SetRenderWindow(renderWindow);
 renderWindowInteractor->AddObserver ( vtkCommand::KeyPressEvent, keypressCallback );

</source>

In this example, the vtkRenderWindowInteractor is listening for the command KeyPressEvent. A complete list of commands that are available can be found [here |http://www.vtk.org/doc/nightly/html/classvtkCommand.html].

Writing the Callback Function

caller

The vtkObject "caller" is a pointer to the observer. In this example, since we attached the vtkCallbackCommand to a vtkRenderWindowInteractor, we can successfully cast "caller" to a vtkRenderWindowInteractor.

<source lang="cpp"> void KeypressCallbackFunction ( vtkObject* caller, long unsigned int eventId, void* clientData, void* callData ) {

 cout << "Keypress callback" << endl;
 
 vtkRenderWindowInteractor *iren = 
     static_cast<vtkRenderWindowInteractor*>(caller);
 cout << "Pressed: " << iren->GetKeySym() << endl;

}

</source>

clientdata

clientdata provides a way to provide access to data that will be necessary in the callback function. You can set this data using the SetClientData function of vtkCallbackCommand. For example, if you want to have access to an instance of a vtkProgrammableFilter in the callback function, you can do:

<source lang="cpp">

 vtkSmartPointer<vtkProgrammableFilter> filter = 
     vtkSmartPointer<vtkProgrammableFilter>::New();
 vtkSmartPointer<vtkCallbackCommand> timerCallback = 
     vtkSmartPointer<vtkCallbackCommand>::New();
 timerCallback->SetCallback ( func );
 timerCallback->SetClientData(filter);

</source>

Then in the callback function, you can cast the clientdata to the expected type: <source lang="cpp"> void func ( vtkObject* caller, long unsigned int eventId, void* clientData, void* callData ) {

 vtkSmartPointer<vtkProgrammableFilter> programmableFilter = 
     static_cast<vtkProgrammableFilter*>(clientData);

} </source>

calldata

calldata is data that may be sent with the callback. For example, when the ProgressEvent event is sent, it sends the progress value as calldata.