# How to add my own module widget to another module?

**URL:** https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628
**Category:** Development
**Tags:** python
**Created:** [December 7, 2022, 2:59pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628 "2022-12-07T14:59:03Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![drobny](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@drobny](https://discourse.slicer.org/u/drobny)
#### Post date: [December 7, 2022, 2:59pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/1 "2022-12-07T14:59:03Z")

</div>

Hi all,  
I have been using Slicer for some basic tasks in the past and just now have started developing my own module. My concept was to simplify the workflow for a clinician to annotate several images. The module should do the communication with an XNAT server to pull the images and push the annotation files (markup JSON files).

Initially, my concept was to create a new GUI that mirrors and wraps the relevant functionality of the Markups module. Learning more about the concept of reusable widgets, I tried to include the widgets I need from Markups. The widget I am missing would be what is in the Control Points collapsible button - mainly the functions on the `activeMarkupTableWidget`. It seems to have not been made available as a widget or the function logic made accessible from outside so that I could easily replicate the functionality.

I then used `slicer.modules.markups.createNewWidgetRepresentation()` to include the Markups module into my module but still was missing the functionality of the `activeMarkupTableWidget`. I tried replicating the setup according to the `.cxx` file but seem to not understand enough of it to connect the data node and actually display the control points in the table.

My next approach was to add my new functionality as a widget into the markups module (and hide all the UI elements not needed). This might actually make the most sense design wise, according to my current understanding. I managed to clean up and simplify the markups module as desired but struggle to see what needs to be done to instantiate my module as a widget.

Trying this command:

```python
slicer.util.getModuleGui("Markups").layout().addWidget(MyModuleWidget())

```

I get the following error:

```auto
'MyModuleWidget' object has no attribute 'createNewWidgetRepresentation'

```

I am a bit confused here. Starting from the wizard to create a scriptable module, I end up with a python file containing the following classes: `MyModule`, `MyModuleWidget`, `MyModuleLogic`, `MyModuleTest`, as well as the GUI file. I would have expected to be able to intantiate the widget as it is. Do I need to implement `createNewWidgetRepresentation` or add some other bits? I couldn’t find examples for this.

I mentioned my path to arrive at this question as any advice/ comment on this would be appreciated as well and might allow a better approach.  
The main question is though: How to add my own module widget to another module?

---

<div class="post-metadata">

### Author: ![drobny](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@drobny](https://discourse.slicer.org/u/drobny)
#### Post date: [December 7, 2022, 3:02pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/2 "2022-12-07T15:02:58Z")

</div>

Here seems to be a related issue with the Markups module:

> [@Would it be possible to have more then one module panel?](https://discourse.slicer.org/t/would-it-be-possible-to-have-more-then-one-module-panel/10880/6):
>
> Actually, while this popups up the module, the module itself is not functional. I am trying particularly with the Markups module, and you can’t see the control points, nor modify their color/size etc with the popup Markups module, while the docked one in the main module panel works fine.

---

<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: [December 7, 2022, 10:20pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/3 "2022-12-07T22:20:19Z")

</div>

`slicer.qSlicerSimpleMarkupsWidget()` is a reusable widget for managing markup control points. For example, it is used in `Fiducial registration wizard` module of SlicerIGT extension.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/2/c2b3295d4261dd10967ec931e5468cc22082db99.png)

You can also create simple custom widget for landmarking, such as in [OrthodonticAnalysis](https://github.com/OrthodonticAnalysis/SlicerOrthodonticAnalysis) extension:

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

We plan to factor out the control point list that you see in Markups module (with all the landmarking features):

> <https://github.com/Slicer/Slicer/issues/6452>
>
> \## Is your feature request related to a problem? Please describe.
> 
> qSlicerSimp…leMarkupsWidget does not support any of the new features that are available in the Markups module's control point table widget.
> 
> \## Describe the solution you'd like
> 
> We would need to create a new qSlicerMarkupsControlPointTableView+Model that could replace both these widgets.
> 
> \## Additional context
> 
> I've started to work on this at some point but then ran out of time. The development branch is available here: https://github.com/lassoan/Slicer/tree/attic/markups-control-points-table-view

I’m not sure if there is any funded project that requires this feature, so you need to wait for a while - or contribute time or funding to make it happen sooner.

---

<div class="post-metadata">

### Author: ![drobny](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@drobny](https://discourse.slicer.org/u/drobny)
#### Post date: [December 8, 2022, 2:31pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/4 "2022-12-08T14:31:46Z")

</div>

Thank you a lot, Andras. These are very useful recommendations! 🙂

Do you also have an advice or a pointer towards how to make one’s widget available to be added to other modules? What has to be done to create an actual widget, not just a full module, from the MyModuleWidget() class?

---

<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: [December 8, 2022, 4:47pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/5 "2022-12-08T16:47:22Z")

</div>

> [@drobny](#):
>
> Do you also have an advice or a pointer towards how to make one’s widget available to be added to other modules?

You can import the widget in a separate class (if you work in Python you can put it into a separate file, but it may also stay in the single module .py file) and import and use it in another module.

Most of the reusable widgets are implemented in Slicer core in C++, but there are a few examples in Python in extensions, for example in [Cardiac Device Simulator module in SlicerHeart](https://github.com/SlicerHeart/SlicerHeart/tree/master/CardiacDeviceSimulator/CardiacDeviceSimulatorUtils).

---

<div class="post-metadata">

### Author: ![drobny](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@drobny](https://discourse.slicer.org/u/drobny)
#### Post date: [December 14, 2022, 4:56pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/6 "2022-12-14T16:56:59Z")

</div>

I wanted to create two widgets in my module, one widget with the main functionality and the second widget that modifies the markup module GUI (to only show the control points table) and attaches the first widget to the markup layout. This is a hack to go around re-implementing the markup control point table.

The problem with this approach is, that I cannot create two widgets using `ScriptedLoadableModuleWidget` and .ui files. When setting up the module and two widget classes in the following way:

```auto
class MyModule(ScriptedLoadableModule):...

class MyModuleWidget(ScriptedLoadableModuleWidget, VTKObservationMixin):...

class MyModuleSecondWidget(ScriptedLoadableModuleWidget, VTKObservationMixin):...

```

I get the following error when calling `ScriptedLoadableModuleWidget.setup(self)` for the second widget:

```auto
AttributeError: module 'modules' has no attribute 'mymodulesecond'

```

I didn’t manage to understand how to create the second widget without slicer expecting a corresponding module.

I then tried to follow the example of the Cardiac Device Simulator module and used `qt.QWidget` instead of `ScriptedLoadableModuleWidget`. To be able to load and use the second .ui file, I had to replace the function `self.layout.addWidget(uiWidget)` with

```auto
layout = qt.QVBoxLayout()
layout.addWidget(uiWidget)
self.setLayout(layout)

```

This has worked for me but I wanted to report my process for future reference and to mention the issue with using two widget classes based on `ScriptedLoadableModuleWidget`.

---

<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: [December 14, 2022, 9:46pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/7 "2022-12-14T21:46:54Z")

</div>

Only the `<ModuleName>Widget` class is special in the sense that Slicer discovers and instantiates that automatically. You can create all other widgets as regular Python classes and instantiate them as usual. If you create a new widget `MyCustomWidget` then you can access it from another module like this:

```python
import MyModule
w = MyModule.MyCustomWidget()

```

---

<div class="post-metadata">

### Author: ![drobny](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@drobny](https://discourse.slicer.org/u/drobny)
#### Post date: [December 15, 2022, 1:56pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/8 "2022-12-15T13:56:53Z")

</div>

Ok, understood.

I think it threw me off, that it doesn’t seem possible to have multiple widget classes using `ScriptedLoadableModuleWidget` in the same module. It took me a while to identify the problem (though I still don’t understand why it behaves like this) and to find the workaround going back to `QWidget`. If this is the intended behaviour of widgets, it could be useful including a second widget setup in the module wizard/ demo 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: [December 15, 2022, 2:39pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/9 "2022-12-15T14:39:18Z")

</div>

You can add any number of widgets from .ui files using `loadUI` - see documentation and example [here](https://slicer.readthedocs.io/en/latest/developer_guide/slicer.html#slicer.util.childWidgetVariables).

---

<div class="post-metadata">

### Author: ![drobny](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@drobny](https://discourse.slicer.org/u/drobny)
#### Post date: [December 15, 2022, 4:03pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/10 "2022-12-15T16:03:48Z")

</div>

When creating two widget classes (in the same module file) as in the wizard demo file using  
`class MyModuleWidget(ScriptedLoadableModuleWidget, VTKObservationMixin):...`,  
I am not able to add both widgets to the module. Both widgets would be expected to be in a accordingly named module.  
Thus, following the module wizard and tutorial, I am not offered the tools for creating a widget that can be reused. I think it would be great extending the demo module by a second widget (that is not a `ScriptedLoadableModuleWidget`) and which is then added to the main `ScriptedLoadableModuleWidget`. For me, as someone new to Slicer development and without experience in QT, it took quite some effort to find a way to do what I wanted.

You provided a lot of useful information that helped me move forward, but the essential step was using `qt.QWidget` for the widget creation which I haven’t seen directly in other modules I was looking at. This knowledge seems key to developing reusable widgets which is a core aim for the widget concept as I understand 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: [December 15, 2022, 4:54pm UTC](https://discourse.slicer.org/t/how-to-add-my-own-module-widget-to-another-module/26628/11 "2022-12-15T16:54:27Z")

</div>

You have only one _module widget_, i.e., the widget that is shown in the left panel when you switch to the module. But you can create many widgets in Qt designer, save each in a ui file, and at runtime instantiate the widgets from the ui files and add them to the module widget.

Creating reusable widgets is an advanced topic, not covered by wizards or tutorials. If you are new to Qt then I would recommend to not start with creating reusable widgets, but use and customize the already existing reusable widgets provided by Qt, CTK, and Slicer.

It is usually not needed to create reusable widgets in Python, because scripting is just used for putting together the end-user workflow from existing components. You rarely if ever need to develop new GUI components in Python.

Can you write a bit about your overall task and plan to implement your solution? We could then probably provide more directly useful answers.
