Continuing processing after interactor (Python)

Dear All,

How to process after interactor.Start()?
I want to interact with the displayed image (as the interactor) but I want at the same time to process the gotten pointer position and add other images to the camera i.e. process after interactor.Start() in the code below.
I tried to launch a thread as commented below but seems that the interactor is ran in exclusive. Seems that the thread stops as the interactor starts.


def func1():
.....
.....
    renderWindow.AddRenderer(renderer)
    interactor = vtk.vtkRenderWindowInteractor()
    interactor.SetRenderWindow(renderWindow) 
    #x = threading.Thread(target=thread_function, args=(renderer,renderWindow))
    #x.start()
    interactor.Initialize()
    renderWindow.Render()
    interactor.Start()

Thanks,

Luís Gonçalves

You’ve got two options.

Ask the interactor to create a repeating timer. In which case it will try to call a function you provide on a timer. See the c++ example here. Python animation example here.

For more flexibility you may also just drive the interactor yourself in your own loop. Here’s the c++ version of that.

if (m_vtkRenderWindow->GetInteractor()->HasObserver(vtkCommand::StartEvent))
{
    m_vtkRenderWindow->GetInteractor()->InvokeEvent(vtkCommand::StartEvent, nullptr);
}

m_vtkRenderWindow->GetInteractor()->Initialize();
m_vtkRenderWindow->Render();

while(running)
{
    // Do stuff here!
    m_vtkRenderWindow->GetInteractor()->ProcessEvents();
    // Or do stuff here!
    m_vtkRenderWindow->Render();
}

m_vtkRenderWindow->Finalize();
m_vtkRenderWindow->GetInteractor()->TerminateApp();

To expand on the previous reply, if you are using the VTK interactors then in general you should write an event-driven application. In a pure VTK app, this means that before you call Start() you should set observers for any events you want to process (see vtkCommand for a list of events). In your case, an observer for a PickEvent might be suitable.

In general, most actions in the application should be driven from user-initiated events (picks, mouse clicks, key presses, etc.). Timer events should only be used in specific situations, e.g. for animation that is not user-driven, or for polling asynchronous tasks.

For example, let’s say that one of your event handlers needs to do something that’s going to take a few seconds (or longer) to complete. In that case, it makes sense for the event handler to start up a background thread, and to also start up a timer that will check every 20ms or so to see if the background thread has finished. When timer callback finds that the thread is finished, it can do whatever is needed to display the results (and at this point the timer can also stop itself, since it has done its job).

The easiest way to do this kind of stuff is with a high-level GUI toolkit such as Qt, rather than relying on VTK alone. VTK events are always synchronous, i.e. you cannot invoke an event in one thread and handle it in another. The signal-slot mechanism in Qt is far more versatile, and automatically handles cross-thread communication.

Thanks to both for all that information.

One question. Does the event handler produce printouts of runtime errors if exists?

Thanks,

Luís Gonçalves

You’ll have to give an example of what you are asking.

If you write a handler for ErrorEvent, then you can do whatever you want to deal with the error. But I think you are asking something different?

No, I am saying about you answered before. The interactor can be interrupted with a keypress and run the handler for that keypress. If I have a runtime error in that handler the interpreter printouts the error?

Since your original question was about Python, when you say “runtime error” do you mean a Python exception? If so, then the error be printed and the program will continue to run. If the runtime error is a C++ exception, then the program will crash. If the error is a VTK error (from vtkErrorMacro in the VTK C++ code), then the error will be displayed the same way that VTK errors are usually displayed (either on the console, or in a separate error window).