Skip to content

Commit

Permalink
Update theme/style sheet handling to enable napari-console to use nap…
Browse files Browse the repository at this point in the history
…ari `font_size` setting (#33)

# References and relevant issues

Closes #32

# Description

Depends on/related to napari/napari#6753

A preview:


![console_font_size](https://github.com/napari/napari-console/assets/16781833/a491c26e-8cd6-4438-939e-3e4d1250f115)

## Notes

* While working on this, I noticed that with napari latest main a
deprecation warning appears (related with using the `as_dict` kwarg from
the `get_theme` function). Added a note about that here.
* To preserve compatibility with napari 0.4.x (at least 0.4.19) the
previous logic was left. The new `style_sheet` kwarg added to the
`_update_theme` method defines if the previous logic needs to be used
(napari 0.5.0 will use the new `style_sheet` kwarg, see
napari/napari#6753)

---------

Co-authored-by: Juan Nunez-Iglesias <[email protected]>
  • Loading branch information
dalthviz and jni authored Nov 6, 2024
1 parent c15d804 commit 463f828
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 19 deletions.
4 changes: 3 additions & 1 deletion napari_console/_tests/test_qt_console.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ def actual_factory(*model_args, viewer_class=Viewer, **model_kwargs):
def test_console(qtbot, make_test_viewer):
"""Test creating the console."""
viewer = make_test_viewer()
console = QtConsole(viewer)
style_sheet = viewer.window._qt_window.styleSheet()
console = QtConsole(viewer, style_sheet=style_sheet)
qtbot.addWidget(console)
assert console.kernel_client is not None
assert console.viewer is viewer
assert console.style_sheet == style_sheet


def test_ipython_console(qtbot, make_test_viewer):
Expand Down
50 changes: 32 additions & 18 deletions napari_console/qt_console.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class QtConsole(RichJupyterWidget):
----------
max_depth : int
maximum number of frames to consider being outside of napari.
style_sheet: str
String representing the style sheet the console should follow
Attributes
----------
Expand All @@ -88,15 +90,19 @@ class QtConsole(RichJupyterWidget):

min_depth: Optional[int]

def __init__(self, viewer: "napari.viewer.Viewer", *, min_depth=1):
def __init__(self, viewer: 'napari.viewer.Viewer', *, min_depth: int = 1, style_sheet: str = ''):
super().__init__()

self.viewer = viewer

self.min_depth = min_depth

# Connect theme update
self.viewer.events.theme.connect(self._update_theme)
if not style_sheet:
# napari <0.5.5 relies on viewer theme event to update the style
# (without passing a style value when creating a console)
self.viewer.events.theme.connect(self._update_theme)

user_variables = {'viewer': self.viewer}

# this makes calling `setFocus()` on a QtConsole give keyboard focus to
Expand Down Expand Up @@ -153,7 +159,7 @@ def __init__(self, viewer: "napari.viewer.Viewer", *, min_depth=1):
self.enable_calltips = False

# Set stylings
self._update_theme()
self._update_theme(style_sheet=style_sheet)

# TODO: Try to get console from jupyter to run without a shift click
# self.execute_on_complete_input = True
Expand Down Expand Up @@ -181,24 +187,32 @@ def _capture(self):
if "NAPARI_EMBED" not in c.frame.f_globals:
self.push(dict(c.namespace))

def _update_theme(self, event=None):
def _update_theme(self, event=None, style_sheet=''):
"""Update the napari GUI theme."""
from napari.utils.theme import get_theme, template
from napari.qt import get_stylesheet
from napari.utils.theme import get_theme

# qtconsole unfortunately won't inherit the parent stylesheet
# so it needs to be directly set
raw_stylesheet = get_stylesheet()
# template and apply the primary stylesheet
# (should probably be done by napari)
# After napari 0.4.11, themes are evented models rather than
# dicts.
theme = get_theme(self.viewer.theme, as_dict=True)
self.style_sheet = template(raw_stylesheet, **theme)

# After napari 0.4.6 the following syntax will be allowed
# self.style_sheet = get_stylesheet(self.viewer.theme)

# so it needs to be directly set when required.
if style_sheet:
# napari >=0.5.5 uses the `style_sheet` kwarg and the `to_rgb_dict` theme method
theme = get_theme(self.viewer.theme).to_rgb_dict()
self.style_sheet = style_sheet
else:
# napari 0.4.x and <0.5.5 doesn't use the `style_sheet` kwarg and uses the deprecated
# `as_dict` kwarg for the `get_theme` function call
from napari.qt import get_stylesheet
from napari.utils.theme import template

theme = get_theme(self.viewer.theme, as_dict=True)
raw_stylesheet = get_stylesheet()
# get template and apply the primary stylesheet
# (should probably be done by napari)
# After napari 0.4.11, themes are evented models rather than
# dicts.
self.style_sheet = template(raw_stylesheet, **theme)

# After napari 0.4.6 the following syntax will be allowed
# self.style_sheet = get_stylesheet(self.viewer.theme)

# Set syntax styling and highlighting using theme
self.syntax_style = theme['syntax_style']
Expand Down

0 comments on commit 463f828

Please sign in to comment.