Would it be possible to have more then one module panel?

I sometimes want to have two (or even more) module tabs open to interact with multiple modules at the same time (as oppose to using the arrows to go back and forth). With the ability of undocking the modules tab, and with multiple screen setups, it think this actually kind of makes sense.

In such case I guess the Module selection drop down needs to be part of the module panel, as oppose to menu bar to enable module selection in each panel independently.

If the module history and favorite modules on toolbar are not convenient enough (e.g., because you want to perform the same workflow multiple times) then having one more module panel would not help much. Instead, you can get more much more convenient, polished GUI by creating a custom scripted module You should be able to put together a GUI panel from the readily available high-level widgets in a few ten minutes using Qt Designer. Potentially you don’t need to write any code, just drag-and-drop the widgets and connect the signals in Qt designer. You only need to write code if you want to run specific processing functions when a button is clicked.

I would be also reluctant to enable unlimited module panels (e.g., dockable panels) because when you look at applications that take this approach, they all end up being extremely hard to use. We get lots of complaints that Slicer is hard to learn, so I would rather work on things that would take us in that direction.

1 Like

Thanks Andras. I do not know anything about QT Designer. Looking at this page it seems it is more suitable for custom build? https://www.slicer.org/wiki/Documentation/Nightly/Developers/Tutorials/QtDesigner

But somehow we can use it in a scripted module?

It’s part of the current scripted module template. In developer mode you can start designer on the module with a single click.

Qt Designer itself starts out with a bunch of panels. Do you find that hard to use? I think they did it for the same reason Murat wants it, so you don’t need so many clicks to get what you need.

If you want to try it out, you can go to the module and then type in the following (replace annotations with the name of the module you want to pop out). If it basically works we could make a hot key or small button for this.

slicer.modules.annotations.widgetRepresentation().setParent(None)
slicer.modules.annotations.widgetRepresentation().show()
1 Like

Thanks Steve. This looks good.

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.

That’s weird - Volume Rendering works fine. Probably Markups and maybe other modules have some other logic that makes it not work in this mode. Does it work for other modules you use often and if so, do you like the mode well enough that we should take it past this prototype stage (e.g. add a button or hotkey for this).

If you would like to create an other widget representation for an existing module, it could be done like this:

>>> markups_module_widget = slicer.modules.annotations.createNewWidgetRepresentation()
>>> markups_module_widget.setMRMLScene(slicer.mrmlScene)
>>> markups_module_widget.show()

Next would be to ensure enter()/exit() method can be called from python and this should allow to have the module UI updated.

Doing so (instead of re-parenting) ensures the existing module panel will work as expected.

Thanks @jcfr this works perfectly!

Found this thread really cool, never knew about this functionality before. I have been playing around with the pop out and wanted to add another point. If you want the pop-out window to stay always on top you can add:

markups_module_widget.setWindowFlag(qt.Qt.WindowStaysOnTopHint)

This will ensure whatever window you have floating will stay on top of the main panel.

I would recommend to put all widgets into the window layout (you can add any number of dockable widgets), because popups can get very confusing. For example,when you switch between applications (Alt+Tab) then it is quite random what ends up being visible and where.

See for example the NodeInfo module if you want to learn how to place additional dockable widgets in the main window.

I have always just built UI files and loaded them with slicer.util.loadUI(). I never thought about accessing them though the slicer.modules module before. I’ll check out the Nodeinfo module!

In the NodeInfo module I notced this signal/slot syntax. Is there a reason not to use the newer syntax self.showInfoButton.clicked.connect(self.onShowInfoClicked)?

I’m not sure what you are referring to exactly, because you should not insert a completely different module’s GUI in your own module GUI. It would contain lots of irrelevant components. Instead, you can have a look at the module GUI and just add those widgets to your module that are relevant to your workflow (with all the customization you need).

I tend to prefer optimizing the code for readability (make it clear that it is a signal, make it clear what arguments it provides), so in general I would choose this syntax:

self.showInfoButton.connect('clicked(bool)', self.onShowInfoClicked)

instead of this:

self.showInfoButton.clicked.connect(self.onShowInfoClicked)

but if both work then it is up to you to choose.

1 Like

I only meant that I never realized I could access my own modules with slicer.modules.myModuleWidget.mySubWidget. I have just been using the other syntax style for signals/slots so was curious to know.