ProcessEvents crash when refresh UI

I capture real time video in thread , process image in slot fuction and try to force update result node in threeDViewWidget by qSlicerApplication::application()->processEvents()
slicer crash when run after several times.
the whole process is about 60ms.
How can i force update renderwindow.

*auto threeDView = qSlicerApplication::application()->layoutManager() \*
  •   ->threeDWidget(0)->threeDView();*
    
  • auto renderWindow = threeDView->renderWindow();*
  • renderWindow->Render();|*
  • //threeDView->forceRender();|*
    this has no change on View

Any suggestion is very appreciated!

You need to use processEvents very carefully, as you can easily create event loops (e.g. a slot that itself calls processEvents and creates an infinite recursion). It looks like you are using C++, so you can use a debugger to see what’s going on with your slots.

We usually capture real-time video in a separate process (e.g, using PLUS) and stream into Slicer via OpenIGTLink. Since the image acquisition happens in another process (we often do it on a different computer, e.g., an ultrasound system) it does not impact interactivity of the application, regardless of how long it takes to acquire (and potentially process, segment, etc.) an image. Running in a separate process also ensures that any instability in the image acquisition process (e.g., crash because the image acquisition hardware is disconnected) does not affect the application, but you can start/stop/restart the acquisition process anytime.

The OpenIGTLink interface module in Slicer takes care of thread-safe update of the images in the scene, so you will not have any crashes. OpenIGTLink is a very lightweight socket-based protocol, which typically adds just a couple of milliseconds latency.

If you insist on running the image acquisition in the same process then you just have to be really careful and knowledgeable. Calling processEvents() from a separate thread should not be necessary, as doing some operations on a background thread does not block the main thread, so event processing on the main thread is already running continuously. You must not call any GUI or rendering related methods from background threads (such as forceRender), because the application will crash. You must not modify the scene content from the background thread, because the application will crash. Instead you always call these methods and modify data on the main thread, based on information that the background thread provides to the main thread via thread-safe communication mechanisms (mutex, queue, etc.). These are all very basic concepts of concurrent processing, yet making everything work correctly usually becomes quite complex in the end. If you don’t want to spend significant amount of time learning all this and then debug random crashes then I would recommend to go with the already implemented and very thoroughly tested OpenIGTLink-based solution.

I add xxxnode->Modified before updateVolumeFromArray,
instead of calling processEvents
and it fixed.

1 Like