Is it possible to import Qt inside a Python scripted CLI module? I want to display an error message to tell the user to modify the input parameters. When I try to import qt I get the following error:
Traceback (most recent call last):
File "/home/ben/projects/SlicerCBM/SlicerFreeSurferCommands/FreeSurferSynthStripSkullStrip/FreeSurferSynthStripSkullStrip.py", line 4, in <module>
import qt
File "/opt/slicer/Slicer-5.2.2-linux-amd64/bin/Python/qt/__init__.py", line 19, in <module>
from PythonQt.private import QObject
ModuleNotFoundError: No module named 'PythonQt'
Traceback (most recent call last):
File "/home/ben/projects/SlicerCBM/SlicerFreeSurferCommands/FreeSurferSynthStripSkullStrip/FreeSurferSynthStripSkullStrip.py", line 130, in <module>
import tkinter
File "/opt/slicer/Slicer-5.2.2-linux-amd64/lib/Python/lib/python3.9/tkinter/__init__.py", line 37, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'
Traceback (most recent call last):
File "/home/ben/projects/SlicerCBM/SlicerFreeSurferCommands/FreeSurferSynthStripSkullStrip/FreeSurferSynthStripSkullStrip.py", line 129, in <module>
slicer.util.errorDisplay("Something wrong.")
File "/opt/slicer/Slicer-5.2.2-linux-amd64/bin/Python/slicer/util.py", line 2668, in errorDisplay
import qt, logging
File "/opt/slicer/Slicer-5.2.2-linux-amd64/bin/Python/qt/__init__.py", line 19, in <module>
from PythonQt.private import QObject
ModuleNotFoundError: No module named 'PythonQt'
As an aside, are the slicer.util functions in general intended to be also used from CLI modules or do they only work in scripted modules?
Python scripted CLI modules must never display any GUI. The user interface is generated automatically by Slicer. The algorithm must not be blocked by waiting for any user inputs. Progress information can be provided to the application by printing XML elements on the process output.
You can implement interactive GUI in Python in Python scripted loadable modules. A Python scripted loadable module can also call CLI modules (implemented in C++ or Python), so if you already have a CLI module then you can add a scripted loadable module if you need more customized, interactive GUI.
All I want to do is display an error if the user doesn’t specify the correct input. I was using argparse like this:
parser.add_argument('-i', '--image', required=True,
help='Input image to skullstrip.')
but it gives very noisy output:
FreeSurfer SynthStrip Skull Strip standard error:
usage: FreeSurferSynthStripSkullStrip.py [-h] -i IMAGE [-o OUT] [-m MASK]
[-g | --gpu | --no-gpu] [-b BORDER]
[--nocsf | --no-nocsf]
FreeSurferSynthStripSkullStrip.py: error: the following arguments are required: -i/--image
FreeSurfer SynthStrip Skull Strip standard output:
/home/ben/projects/SlicerCBM/SlicerFreeSurferCommands/FreeSurferSynthStripSkullStrip/FreeSurferSynthStripSkullStrip.py
The other alternative, which is more flexible is this:
if not args.out and not args.mask:
print("Error: User must request output Stripped Volume, Mask Volume, or both.")
sys.exit(1)
which gives the following output:
FreeSurfer SynthStrip Skull Strip standard output:
/home/ben/projects/SlicerCBM/SlicerFreeSurferCommands/FreeSurferSynthStripSkullStrip/FreeSurferSynthStripSkullStrip.py
Error: User must request output Stripped Volume, Mask Volume, or both.
Is there a recommended way to do this? In C++ CLI modules the PARSE_ARGS macro seems to take care of this. By the way, where is that macro defined? I tried to search for it but couldn’t find it.