# Workflow that brings together a few modules as tabs in a unifying parent module.

**URL:** <https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314>\
**Category:** Development\
**Created:** [January 8, 2019, 8:54pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314 "2019-01-08T20:54:48Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![NormandRbert](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/normandrbert/32/2975_2.png) [@NormandRbert](https://discourse.slicer.org/u/NormandRbert)\
**Post date:** [January 8, 2019, 8:54pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/1 "2019-01-08T20:54:48Z")

</div>

Creating a workflow that brings together a few existing and new custom modules as tabs in a unifying parent module. I am wondering if anyone has used this approach. Sensible? Bad idea? I have inherited code to do this but I am concerned about the design of it. I would like to see a “best” practice example if one exists.

---

<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:** [January 8, 2019, 9:00pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/2 "2019-01-08T21:00:30Z")

</div>

Typically you would not reuse entire module widgets to build your workflow interface, because each module widget is expected to be a singleton. Instead, you build it from high-level widgets.

Modules widgets that are implemented well are already built up from high-level reusable widgets. If you come across a module that you would like to use and not implemented like this then let us know and we’ll see if reusable widgets can be easily exposed.

---

<div class="post-metadata">

**Author:** ![NormandRobert](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/normandrobert/32/4818_2.png) [@NormandRobert](https://discourse.slicer.org/u/NormandRobert)\
**Post date:** [January 8, 2019, 9:08pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/3 "2019-01-08T21:08:47Z")

</div>

Andras can you pick one or more python module which you think embodies these best practices? Thanks

---

<div class="post-metadata">

**Author:** ![adamrankin](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/adamrankin/32/155_2.png) [@adamrankin](https://discourse.slicer.org/u/adamrankin)\
**Post date:** [January 8, 2019, 9:09pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/4 "2019-01-08T21:09:13Z")

</div>

As @lassoan said, reusable widgets are the best approach. If they are not available and the authors don’t have the bandwidth to support you, you could try your idea (others have).

I recommend you investigate the [ctkWorkflowWidget](http://www.commontk.org/index.php/Documentation/ctkWorkflowWidget) as this is what it was designed for.

I personally like this approach for clinician workflows, as it limits the decisions they have to make/content they have to learn. They can always override your workflow by going to a desired module (unless you’ve hidden the module navigator widget).

---

<div class="post-metadata">

**Author:** ![NormandRobert](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/normandrobert/32/4818_2.png) [@NormandRobert](https://discourse.slicer.org/u/NormandRobert)\
**Post date:** [January 8, 2019, 9:20pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/5 "2019-01-08T21:20:53Z")

</div>

I was also interested in doing this to create a clinical workflow.

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [January 8, 2019, 10:14pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/6 "2019-01-08T22:14:05Z")

</div>

> [@lassoan](#):
>
> because each module widget is expected to be a singleton

That said, if complete UI of modules need to be composed together. One could use, the function `createNewWidgetRepresentation()`

For example:

```python
w = slicer.modules.gaussianblurimagefilter.createNewWidgetRepresentation()
w.show()

w = slicer.modules.segmenteditor.createNewWidgetRepresentation()
w.show()

```

---

<div class="post-metadata">

**Author:** ![NormandRobert](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/normandrobert/32/4818_2.png) [@NormandRobert](https://discourse.slicer.org/u/NormandRobert)\
**Post date:** [January 8, 2019, 11:02pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/7 "2019-01-08T23:02:00Z")

</div>

I was not going to go there 🙂 but the solution I inherited (below) has some similarity to what you suggested and then I noticed that “my” version caused the UI creation code to be called twice, realized it was ugly causing me to start this thread. Looking into your variation which uses “show”. Also thinking that since I am authoring the tabbed modules I should consider Andras’ advice by making those “more” re-usable. Thank you

# Triggers UI creation

```
igtConnection = slicer.modules.igtconnection.createNewWidgetRepresentation()
self.igtConnectionModule = IGTConnection.IGTConnectionWidget(igtConnection)
self.tabWidget.addTab(self.qWidget1, "IGT Connection")
# Triggers UI creation again bad?
self.igtConnectionModule.setup(qFormLayout1)
```

---

<div class="post-metadata">

**Author:** ![NormandRbert](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/normandrbert/32/2975_2.png) [@NormandRbert](https://discourse.slicer.org/u/NormandRbert)\
**Post date:** [January 9, 2019, 9:30pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/8 "2019-01-09T21:30:42Z")

</div>

Been thinking about what you wrote. Imagine a module called SandBox, a template generated with the python script found in the Slicer 3D source tree. It produces the classes SandBox, SandBoxWidget, SandBoxLogic, SandBoxTest.

So do you recommend that I create a new class say SandBoxWidgetUI with mostly GUI stuff and use it in another module like this?  
import SandBox  
sdb=SandBox.SandBoxWidgetUI()

It seems that the names SandBox, SandBoxWidget, SandBoxLogic, SandBoxTest are special and Slicer looks for these functions and makes them available via slicer.modules… unlike my new SandBoxWidgetUI class. I could alternatively reorganize the existing SandBoxWidget() class to make it more useful from another module but that seems less flexible as I would inherit other bits like a constructor I might not need.

---

<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:** [January 9, 2019, 10:54pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/9 "2019-01-09T22:54:53Z")

</div>

For complex GUI, you can use Qt designer to create a .ui file and instantiate the widget from that.

---

<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:** [January 10, 2019, 1:24pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/10 "2019-01-10T13:24:02Z")

</div>

I like the idea of having a “UI” class be part of the auto-generated module code. It would encourage best practices. It would mean updating the templates.

---

<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:** [January 10, 2019, 2:17pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/11 "2019-01-10T14:17:28Z")

</div>

I haven’t thought about promoting using .ui files to the general public, but I agree that it could work well.

To make Qt designer (with all custom ctk, qMRML, Slicer widgets) available without requiring users to install a compatible version of Qt, we would need to bundle Qt designer binaries in the installation package. It should be no problem, as it requires only a few extra files of a total size of 6 MB (designer.exe, Qt5Designer.dll, and Qt5DesignerComponents.dll; Qt designer plugins are already included). @jcfr what do you think?

In addition to bundling designer executable, we should add an “Edit .ui file” button to the Reload&Test section and add an ExtensionWizard template.

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [January 10, 2019, 2:41pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/12 "2019-01-10T14:41:14Z")

</div>

> [@lassoan](#):
>
> what do you think?

That seems reasonable.

Additional libraries would have to be listed [here](https://github.com/Slicer/Slicer/blob/53be7ad66d1d6c5655352b5a028c2f22348c1842/CMake/SlicerBlockInstallQt.cmake#L82-L90) and designer executable could be installed using approach done for [QtWebEngineProcess](https://github.com/Slicer/Slicer/blob/53be7ad66d1d6c5655352b5a028c2f22348c1842/CMake/SlicerBlockInstallQt.cmake#L94-L96).

And if build system not already take care of fixing up the executable … we may have to do something specific.

---

<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:** [January 10, 2019, 3:05pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/13 "2019-01-10T15:05:16Z")

</div>

Wow, bundling Qt Designer with Slicer is a fascinating idea. That could be convenient for everyone, but I also imaging there’s a category of people who might contribute to the ui who wouldn’t think of doing it in C++ or Python but would like using the designer.

I suppose the logical next step would be including all of Qt Creator? We need to draw the line somewhere but this could be an optional install or developer extension.

---

<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:** [January 10, 2019, 5:37pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/14 "2019-01-10T17:37:59Z")

</div>

I’ve tried to update the current scripted module template to use a .ui file to generate GUI and it worked really well. It reduced and simplified the code a lot.

Reload works nicely: to update the GUI, it is enough to save the .ui file in Qt Designer and click Reload in Slicer.

Widget variables can be automatically exposed as `self.ui.myWidget` (similarly how variables are accessible in C++ by generating a skeleton file).

I’ve submitted a pull request so that you can have a look: [https://github.com/Slicer/Slicer/pull/1072/files#diff-c12bcbe4f4bab89847136fc032496bd4R36](https://github.com/Slicer/Slicer/pull/1072/files#diff-c12bcbe4f4bab89847136fc032496bd4R36)

@jcfr It works so nicely that I think it would worth the time adding designer to the package. Could you have a look? If it’s very easy then it might make sense to include it in 4.10.1.

---

<div class="post-metadata">

**Author:** ![jamesobutler](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jamesobutler/32/7511_2.png) [@jamesobutler](https://discourse.slicer.org/u/jamesobutler)\
**Post date:** [January 10, 2019, 6:12pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/15 "2019-01-10T18:12:20Z")

</div>

My group has been using Qt Designer for generating UI files and using them in our Slicer python code using `slicer.util.loadUI()` for well over a year now. Qt Designer definitely helps with quick prototyping of GUIs and we generally prefer this unless the widget is something extremely simple. For beginners, coding QLayout policies and such is really intimidating and difficult to understand without playing around with something like Qt Designer.

---

<div class="post-metadata">

**Author:** ![NormandRbert](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/normandrbert/32/2975_2.png) [@NormandRbert](https://discourse.slicer.org/u/NormandRbert)\
**Post date:** [January 10, 2019, 7:12pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/16 "2019-01-10T19:12:12Z")

</div>

I think it is also valuable to maintain the simple template that can be generated via the python script which Jean-Christophe Fillion-Robin et Steve Pieper wrote some years ago. I also think that said script should be in some bin directory associated with slicer binary as well so you don’t have to download the source to get it. It gives you a quick path to writing a “hello world” module.

---

<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:** [January 10, 2019, 7:16pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/17 "2019-01-10T19:16:34Z")

</div>

> [@NormandRbert](#):
>
> I think it is also valuable to maintain the simple template

We’ll maintain both scripted module templates (the current one where GUI is created by scripting, and the new one where GUI is loaded from .ui file). ExtensionWizard module can generate modules from these templates.

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [January 13, 2019, 7:43pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/18 "2019-01-13T19:43:27Z")

</div>

Following [r27706](http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27706), Qt designer is expected to be packages on the three platform.

On Linux and Windows, it should be started using `./Slicer --designer`, on macOS, it should be directly started.

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [January 13, 2019, 7:44pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/19 "2019-01-13T19:44:24Z")

</div>

Thinking more about it, we will have to generate a dedicated launcher (similarly to what is done for Python) because we must set variables like `QT_PLUGIN_PATH` also on macOS

---

<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:** [January 13, 2019, 8:19pm UTC](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314/20 "2019-01-13T20:19:59Z")

</div>

If module UI file is found then a new button “Edit UI” appears in Reload&Test section of scripted modules. That button relies on a slicer.util function that uses Slicer --designer to launch the designer. So, it would be great if this would work on all platforms.

Currently, the button is only shown for non-installed Slicer. Now that designer is bundled with installed Slicer, too, the button should be shown for installed Slicer as well. @jcfr please make the change (I’m traveling).

[Next page](https://discourse.slicer.org/t/workflow-that-brings-together-a-few-modules-as-tabs-in-a-unifying-parent-module/5314.md?page=2)
