5
5
import matplotlib
6
6
import matplotlib .style as mplstyle
7
7
import napari
8
+ from napari .utils .events import Event
8
9
from napari .utils .theme import get_theme
9
10
from matplotlib .backends .backend_qtagg import ( # type: ignore[attr-defined]
10
11
FigureCanvasQTAgg ,
@@ -56,9 +57,6 @@ def __init__(
56
57
self .canvas .figure .set_layout_engine ("constrained" )
57
58
self .toolbar = NapariNavigationToolbar (self .canvas , parent = self )
58
59
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
62
60
self .viewer .events .theme .connect (self ._on_napari_theme_changed )
63
61
64
62
self .setLayout (QVBoxLayout ())
@@ -70,24 +68,6 @@ def figure(self) -> Figure:
70
68
"""Matplotlib figure."""
71
69
return self .canvas .figure
72
70
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
-
91
71
def add_single_axes (self ) -> None :
92
72
"""
93
73
Add a single Axes to the figure.
@@ -99,11 +79,16 @@ def add_single_axes(self) -> None:
99
79
with mplstyle .context (self .napari_theme_style_sheet ):
100
80
self .axes = self .figure .add_subplot ()
101
81
102
- def _on_napari_theme_changed (self ) -> None :
82
+ def _on_napari_theme_changed (self , event : Event ) -> None :
103
83
"""
104
84
Called when the napari theme is changed.
85
+
86
+ Parameters
87
+ ----------
88
+ event : napari.utils.events.Event
89
+ Event that triggered the callback.
105
90
"""
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 ))
107
92
self ._replace_toolbar_icons ()
108
93
109
94
def _napari_theme_has_light_bg (self ) -> bool :
@@ -214,15 +199,18 @@ def current_z(self) -> int:
214
199
"""
215
200
return self .viewer .dims .current_step [0 ]
216
201
217
- def _on_napari_theme_changed (self ) -> None :
202
+ def _on_napari_theme_changed (self , event : Event ) -> None :
218
203
"""Update MPL toolbar and axis styling when `napari.Viewer.theme` is changed.
219
204
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.
222
209
"""
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 ()
226
214
227
215
def _setup_callbacks (self ) -> None :
228
216
"""
@@ -256,12 +244,13 @@ def _draw(self) -> None:
256
244
# Clearing axes sets new defaults, so need to make sure style is applied when
257
245
# this happens
258
246
with mplstyle .context (self .napari_theme_style_sheet ):
247
+ # everything should be done in the style context
259
248
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]
265
254
266
255
def clear (self ) -> None :
267
256
"""
0 commit comments