55import matplotlib
66import matplotlib .style as mplstyle
77import napari
8+ from napari .utils .events import Event
89from napari .utils .theme import get_theme
910from matplotlib .backends .backend_qtagg import ( # type: ignore[attr-defined]
1011 FigureCanvasQTAgg ,
@@ -56,9 +57,6 @@ def __init__(
5657 self .canvas .figure .set_layout_engine ("constrained" )
5758 self .toolbar = NapariNavigationToolbar (self .canvas , parent = self )
5859 self ._replace_toolbar_icons ()
59- # callback to update when napari theme changed
60- # TODO: this isn't working completely (see issue #140)
61- # most of our styling respects the theme change but not all
6260 self .viewer .events .theme .connect (self ._on_napari_theme_changed )
6361
6462 self .setLayout (QVBoxLayout ())
@@ -70,24 +68,6 @@ def figure(self) -> Figure:
7068 """Matplotlib figure."""
7169 return self .canvas .figure
7270
73- #@property
74- #def mpl_style_sheet_path(self) -> Path:
75- # """
76- # Path to the set Matplotlib style sheet.
77- # """
78- # if self._mpl_style_sheet_path is not None:
79- # return self._mpl_style_sheet_path
80- # elif (_CUSTOM_STYLE_PATH).exists():
81- # return _CUSTOM_STYLE_PATH
82- # elif self._napari_theme_has_light_bg():
83- # return Path(__file__).parent / "styles" / "light.mplstyle"
84- # else:
85- # return Path(__file__).parent / "styles" / "dark.mplstyle"
86-
87- #@mpl_style_sheet_path.setter
88- #def mpl_style_sheet_path(self, path: Path) -> None:
89- # self._mpl_style_sheet_path = Path(path)
90-
9171 def add_single_axes (self ) -> None :
9272 """
9373 Add a single Axes to the figure.
@@ -99,11 +79,16 @@ def add_single_axes(self) -> None:
9979 with mplstyle .context (self .napari_theme_style_sheet ):
10080 self .axes = self .figure .add_subplot ()
10181
102- def _on_napari_theme_changed (self ) -> None :
82+ def _on_napari_theme_changed (self , event : Event ) -> None :
10383 """
10484 Called when the napari theme is changed.
85+
86+ Parameters
87+ ----------
88+ event : napari.utils.events.Event
89+ Event that triggered the callback.
10590 """
106- self .napari_theme_style_sheet = style_sheet_from_theme (get_theme (self . napari_viewer . theme , as_dict = False ))
91+ self .napari_theme_style_sheet = style_sheet_from_theme (get_theme (event . value , as_dict = False ))
10792 self ._replace_toolbar_icons ()
10893
10994 def _napari_theme_has_light_bg (self ) -> bool :
@@ -214,15 +199,18 @@ def current_z(self) -> int:
214199 """
215200 return self .viewer .dims .current_step [0 ]
216201
217- def _on_napari_theme_changed (self ) -> None :
202+ def _on_napari_theme_changed (self , event : Event ) -> None :
218203 """Update MPL toolbar and axis styling when `napari.Viewer.theme` is changed.
219204
220- Note:
221- At the moment we only handle the default 'light' and 'dark' napari themes.
205+ Parameters
206+ ----------
207+ event : napari.utils.events.Event
208+ Event that triggered the callback.
222209 """
223- super ()._on_napari_theme_changed ()
224- self .clear ()
225- self .draw ()
210+ super ()._on_napari_theme_changed (event )
211+ # use self._draw instead of self.draw to cope with redraw while there are no
212+ # layers, this makes the self.clear() obsolete
213+ self ._draw ()
226214
227215 def _setup_callbacks (self ) -> None :
228216 """
@@ -256,12 +244,13 @@ def _draw(self) -> None:
256244 # Clearing axes sets new defaults, so need to make sure style is applied when
257245 # this happens
258246 with mplstyle .context (self .napari_theme_style_sheet ):
247+ # everything should be done in the style context
259248 self .clear ()
260- if self .n_selected_layers in self .n_layers_input and all (
261- isinstance (layer , self .input_layer_types ) for layer in self .layers
262- ):
263- self .draw ()
264- self .canvas .draw () # type: ignore[no-untyped-call]
249+ if self .n_selected_layers in self .n_layers_input and all (
250+ isinstance (layer , self .input_layer_types ) for layer in self .layers
251+ ):
252+ self .draw ()
253+ self .canvas .draw () # type: ignore[no-untyped-call]
265254
266255 def clear (self ) -> None :
267256 """
0 commit comments