When I print in a Python CLI module, all the messages are displayed after the module has completed. Is there any way to print the messages as they occur in real time during execution?
Python CLI (like C++ CLI) modules are very special purpose. If they don’t suit your needs you are much better off writing a scripted module, or wrapping your CLI in a more general purpose script.
I’m developing an extension to run some FreeSurfer commands inside Slicer. Python CLI modules seem perfect because all I need is a GUI for running existing external commands. So far I have the SynthStrip command implemented and it works very well. The only issue is there is no way to know what is happening while the module is running, which for some commands might take several minutes or longer. As far as I understand, a scripted module would block the GUI, which would not be a good trade-off I think.
Right, it makes sense to run these as separate processes, but they don’t need to use the CLI infrastructure, which is really designed to be used for very simple use cases where autogenerating the GUI was preferred. Basically the original motivation for C++ CLIs was to easily port a bunch of ITK example programs for use in Slicer.
Instead you can launch and manage processes using python, most cleanly with the QProcess inftrastructure, that gives you a clean cross platform signals-and-slots based interface for managing IO. You may want to build on the ParallelProcessing extension or just learn from how it use QProcess. The same approach is used in the DICOM module.
If the process provides some output then you can capture that and print to the output using XML tags described here.
See for example in ModelMaker CLI module:
You don’t have to block the GUI, especially if work is done in a different process. I find that most often I block the GUI (just leave a Cancel
button enabled to allow cancelling the operation) because it makes things a bit simpler. But if you want the user to be able to continue using Slicer then you can use the CLI infrastructure to run executables, or as @pieper sugested use Qt classes (and to get notified about process via signals/slots); or use Python functions (and use QTimer to check the process state and outputs).
Thanks for the advice. I’ll try rewriting the extension using scripted modules.