-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path_widget.py
86 lines (75 loc) · 3.29 KB
/
_widget.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"""
This module contains four napari widgets declared in
different ways:
- a pure Python function flagged with `autogenerate: true`
in the plugin manifest. Type annotations are used by
magicgui to generate widgets for each parameter. Best
suited for simple processing tasks - usually taking
in and/or returning a layer.
- a `magic_factory` decorated function. The `magic_factory`
decorator allows us to customize aspects of the resulting
GUI, including the widgets associated with each parameter.
Best used when you have a very simple processing task,
but want some control over the autogenerated widgets. If you
find yourself needing to define lots of nested functions to achieve
your functionality, maybe look at the `Container` widget!
- a `magicgui.widgets.Container` subclass. This provides lots
of flexibility and customization options while still supporting
`magicgui` widgets and convenience methods for creating widgets
from type annotations. If you want to customize your widgets and
connect callbacks, this is the best widget option for you.
- a `QWidget` subclass. This provides maximal flexibility but requires
full specification of widget layouts, callbacks, events, etc.
References:
- Widget specification: https://napari.org/stable/plugins/guides.html?#widgets
- magicgui docs: https://pyapp-kit.github.io/magicgui/
Replace code below according to your needs.
"""
from typing import TYPE_CHECKING
from magicgui.widgets import CheckBox, Container, create_widget
from skimage.util import img_as_float
if TYPE_CHECKING:
import napari
# if we want even more control over our widget, we can use
# magicgui `Container`
class ImageThreshold(Container):
def __init__(self, viewer: "napari.viewer.Viewer"):
super().__init__()
self._viewer = viewer
# use create_widget to generate widgets from type annotations
self._image_layer_combo = create_widget(
label="Image", annotation="napari.layers.Image"
)
self._threshold_slider = create_widget(
label="Threshold", annotation=float, widget_type="FloatSlider"
)
self._threshold_slider.min = 0
self._threshold_slider.max = 1
# use magicgui widgets directly
self._invert_checkbox = CheckBox(text="Keep pixels below threshold")
# connect your own callbacks
self._threshold_slider.changed.connect(self._threshold_im)
self._invert_checkbox.changed.connect(self._threshold_im)
# append into/extend the container with your widgets
self.extend(
[
self._image_layer_combo,
self._threshold_slider,
self._invert_checkbox,
]
)
def _threshold_im(self):
image_layer = self._image_layer_combo.value
if image_layer is None:
return
image = img_as_float(image_layer.data)
name = image_layer.name + "_thresholded"
threshold = self._threshold_slider.value
if self._invert_checkbox.value:
thresholded = image < threshold
else:
thresholded = image > threshold
if name in self._viewer.layers:
self._viewer.layers[name].data = thresholded
else:
self._viewer.add_labels(thresholded, name=name)