Custom theme dictionary

Recently I came across the napari.Viewer.theme attribute which currently accepts two keys: “dark” and “light”. While this is nice, I was looking to get a bit more flexibility in terms of setting up the style. One could add a custom theme dicitonary to napari.utils.theme but that would imply forking napari, which I don’t want to do. So my question is, is there a way to set the style dictionary other than hard-coding a dictionay in the theme module?

Thanks ahead!

1 Like

There isn’t currently a way to do that, no. You could make a feature request here if you like: https://github.com/napari/napari/issues/new?template=feature_request.md

2 Likes

Further to this, I found a solution that may come handy to someone else so pasting it here. One can monkey patch the viewer a bit and modify the style by accessing setStylesheet or setStyle:

viewer = napari.Viewer()
viewer.window.qt_viewer.setStylesheet(foo)

Actually, it’s pretty easy to add a custom theme at runtime, and this doesn’t imply forking (or even require a PR). Just create a new dict that mimics the keys of one of the existing values in napari.utils.theme.palettes, and change any of values you’d like, and then add your new dict to napari.utils.theme.palettes:

import napari

# copy an existing theme for simplicity
my_theme = napari.utils.theme.palettes['dark'].copy()
# change what you want
my_theme.update({
    'background': 'rgb(29, 53, 87)',
    'foreground': 'rgb(69, 123, 157)'
})
# add your theme to the palettes
napari.utils.theme.palettes['my_theme'] = my_theme

viewer = napari.Viewer()
# use it!
viewer.theme = 'my_theme'

The one main caveat here, is that currently you must have the value for the "folder" key in your theme dict be either “dark” or “light” (this will determine icon colors) … this is because the icons are pre-generated from SVG files at launch. To be able to adjust icon colors, we’ll need to expose more control, likely as a plugin. Adjustable themes was one of the early proposals for plugin ideas, but it hasn’t been done yet.

… but if you want to change things besides colors, then yes, you’ll need use the full setStylesheet trick you mentioned above

2 Likes