Skip to content

Commit

Permalink
ENH: Refactor HomeWidget to support custom toolbars
Browse files Browse the repository at this point in the history
Improves the HomeWidget class by introducing a more flexible and scalable
approach to managing custom toolbars in the application:

- Adds toolbarNames property to dynamically manage toolbar names
- Refactors the modifyWindowUI method to create and manage multiple
  custom toolbars, introducing the following functions:
  - `initializeAppToolBar`: Creates a parent toolbar for the application.
  - `addToolBar`: Helper method to initialize and parent new custom toolbars to the application toolbar.
  - `initializeSettingsToolBar`: Creates the settings toolbar with the gear icon button to toggle
    visibility of the settings dialog.
  • Loading branch information
jcfr committed Aug 21, 2024
1 parent 085453f commit a46496f
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
6 changes: 6 additions & 0 deletions {{cookiecutter.project_name}}/.ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ extend-ignore = [
"Q003",
"W191",
]

flake8-annotations.suppress-dummy-args = true
flake8-annotations.suppress-none-returning = true
isort.known-third-party = [
Expand All @@ -69,3 +70,8 @@ isort.known-first-party = [
"Resources",
]
pydocstyle.convention = "pep257"

[lint.per-file-ignores]
# To conveniently support declaring instance variable in the HomeWidget
# class, disable "RUF012: Mutable class attributes should be annotated"
"Modules/Scripted/Home/Home.py" = ["RUF012"]
49 changes: 41 additions & 8 deletions {{cookiecutter.project_name}}/Modules/Scripted/Home/Home.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Optional
from collections.abc import Mapping
from typing import Final, Optional

import qt
import slicer
Expand Down Expand Up @@ -39,6 +40,15 @@ class HomeWidget(ScriptedLoadableModuleWidget, VTKObservationMixin):
https://github.com/Slicer/Slicer/blob/main/Base/Python/slicer/ScriptedLoadableModule.py
"""

APP_TOOLBAR_NAME: Final[str] = "appToolBar"

@property
def toolbarNames(self) -> list[str]:
return [str(k) for k in self._toolbars]

# Members
_toolbars: Mapping[str, qt.QToolBar] = {}

def __init__(self, parent: Optional[qt.QWidget]):
"""Called when the application opens the module the first time and the widget is initialized."""
ScriptedLoadableModuleWidget.__init__(self, parent)
Expand Down Expand Up @@ -77,7 +87,7 @@ def setSlicerUIVisible(self, visible: bool):
exemptToolbars = [
"MainToolBar",
"ViewToolBar",
"CustomToolBar",
*self.toolbarNames,
]
slicer.util.setDataProbeVisible(visible)
slicer.util.setMenuBarsVisible(visible, ignore=exemptToolbars)
Expand All @@ -89,15 +99,38 @@ def setSlicerUIVisible(self, visible: bool):
slicer.util.setToolbarsVisible(visible, keepToolbars)

def modifyWindowUI(self):
# Custom toolbar
"""Customize the entire user interface to resemble the custom application"""
# Custom toolbars
self.initializeAppToolBar()
self.initializeSettingsToolBar()

def initializeAppToolBar(self):
"""Create parent toolbar for the application"""
appToolBar = qt.QToolBar(HomeWidget.APP_TOOLBAR_NAME)
appToolBar.name = HomeWidget.APP_TOOLBAR_NAME
appToolBar.setMovable(False)
appToolBar.setFloatable(False)
mainToolBar = slicer.util.findChild(slicer.util.mainWindow(), "MainToolBar")
self.CustomToolBar = qt.QToolBar("CustomToolBar")
self.CustomToolBar.name = "CustomToolBar"
slicer.util.mainWindow().insertToolBar(mainToolBar, self.CustomToolBar)
slicer.util.mainWindow().insertToolBar(mainToolBar, appToolBar)
self._toolbars[appToolBar.name] = appToolBar

def addToolBar(self, toolBarName: str) -> qt.QToolBar:
"""Helper method to initialize a new custom toolbar and parent it to the application toolbar"""
self._toolbars[toolBarName] = qt.QToolBar(toolBarName)
self._toolbars[toolBarName].name = toolBarName
self._toolbars[toolBarName].setMovable(False)
self._toolbars[toolBarName].setFloatable(False)
slicer.util.mainWindow().insertToolBar(self._toolbars[HomeWidget.APP_TOOLBAR_NAME], self._toolbars[toolBarName])
return self._toolbars[toolBarName]

def initializeSettingsToolBar(self):
"""Create toolbar and dialog for app settings"""
settingsToolBar = self.addToolBar("SettingsToolBar")

# Settings dialog
gearIcon = qt.QIcon(self.resourcePath("Icons/Gears.png"))
self.settingsAction = self.CustomToolBar.addAction(gearIcon, "")
self.settingsAction = settingsToolBar.addAction(gearIcon, "")

# Settings dialog
self.settingsDialog = slicer.util.loadUI(self.resourcePath("UI/Settings.ui"))
self.settingsUI = slicer.util.childWidgetVariables(self.settingsDialog)
self.settingsUI.CustomUICheckBox.toggled.connect(self.setCustomUIVisible)
Expand Down

0 comments on commit a46496f

Please sign in to comment.