# How to import Qt in Python scripted CLI module?

**URL:** <https://discourse.slicer.org/t/how-to-import-qt-in-python-scripted-cli-module/29509>\
**Category:** Development\
**Created:** [May 17, 2023, 2:59pm UTC](https://discourse.slicer.org/t/how-to-import-qt-in-python-scripted-cli-module/29509 "2023-05-17T14:59:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![benzwick](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/benzwick/32/80521_2.png) [@benzwick](https://discourse.slicer.org/u/benzwick)\
**Post date:** [May 17, 2023, 2:59pm UTC](https://discourse.slicer.org/t/how-to-import-qt-in-python-scripted-cli-module/29509/1 "2023-05-17T14:59:17Z")

</div>

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:

```auto
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'

```

---

<div class="post-metadata">

**Author:** ![benzwick](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/benzwick/32/80521_2.png) [@benzwick](https://discourse.slicer.org/u/benzwick)\
**Post date:** [May 17, 2023, 3:27pm UTC](https://discourse.slicer.org/t/how-to-import-qt-in-python-scripted-cli-module/29509/2 "2023-05-17T15:27:54Z")

</div>

I also tried `import tkinter`:

```auto
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'

```

This seems like the simplest way to do it:

```auto
    import slicer.util
    slicer.util.errorDisplay("Something wrong.")

```

but it also fails

```auto
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?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 17, 2023, 4:07pm UTC](https://discourse.slicer.org/t/how-to-import-qt-in-python-scripted-cli-module/29509/3 "2023-05-17T16:07:17Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![benzwick](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/benzwick/32/80521_2.png) [@benzwick](https://discourse.slicer.org/u/benzwick)\
**Post date:** [May 17, 2023, 4:22pm UTC](https://discourse.slicer.org/t/how-to-import-qt-in-python-scripted-cli-module/29509/4 "2023-05-17T16:22:54Z")

</div>

> [@lassoan](#):
>
> The algorithm must not be blocked by waiting for any user inputs.

That makes a lot of sense.

> [@lassoan](#):
>
> Progress information can be provided to the application by printing XML elements on the process output.

Is there an example of this somewhere?

All I want to do is display an error if the user doesn’t specify the correct input. I was using argparse like this:

```auto
    parser.add_argument('-i', '--image', required=True,
                        help='Input image to skullstrip.')

```

but it gives very noisy output:

```plaintext
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:

```auto
    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:

```plaintext
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.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 17, 2023, 4:32pm UTC](https://discourse.slicer.org/t/how-to-import-qt-in-python-scripted-cli-module/29509/5 "2023-05-17T16:32:27Z")

</div>

If you print something on the error output and the process returns with an error then the error message is displayed in the CLI module GUI:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/4/a4b604069ff3b84920880e215d8eee512242e25e.png)

Progress reporting is described here: [Documentation/Nightly/Developers/SlicerExecutionModel - Slicer Wiki](https://www.slicer.org/wiki/Documentation/Nightly/Developers/SlicerExecutionModel#Showing_Progress_in_an_Application)

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [May 17, 2023, 5:12pm UTC](https://discourse.slicer.org/t/how-to-import-qt-in-python-scripted-cli-module/29509/6 "2023-05-17T17:12:23Z")

</div>

> [@benzwick](#):
>
> 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.

This is autogenerated from the XML description of the CLI, so you can find it in the build tree for the module.
