def __init__(self, napari_viewer: Viewer): super().__init__(layout="vertical") self.napari_viewer = napari_viewer self.search_type = create_widget(annotation=SearchType, label="Search type") self.search_type.changed.connect(self._component_num_changed) self.component_selector = SpinBox(name="Label number", min=0) self.component_selector.changed.connect(self._component_num_changed) self.labels_layer = create_widget(annotation=Labels, label="ROI", options={}) self.labels_layer.changed.connect(self._update_roi_info) self.stop = PushButton(name="Stop") self.stop.clicked.connect(self._stop) self.roi_info = None layout = HBox( widgets=( self.search_type, self.component_selector, ) ) layout2 = HBox( widgets=( self.labels_layer, self.stop, ) ) self.insert(0, layout) self.insert(1, layout2)
def __init__(self, napari_viewer: Viewer): super().__init__() self.viewer = napari_viewer self.settings = get_settings() self.roi_select = create_widget(annotation=Labels, label="ROI", options={}) self.mask_select = create_widget(annotation=Optional[Labels], label="Base mask", options={}) self.mask_widget = NapariMaskWidget(self.settings, self.roi_select) self.create = QPushButton("Create") self.name = QLineEdit() self.name.setText(self.settings.get("mask_create_name", "Mask")) layout = QVBoxLayout() layout2 = QHBoxLayout() layout2.addWidget(QLabel("ROI")) layout2.addWidget(self.roi_select.native) layout.addLayout(layout2) layout2 = QHBoxLayout() layout2.addWidget(QLabel("Base mask")) layout2.addWidget(self.mask_select.native) layout.addLayout(layout2) layout2 = QHBoxLayout() layout2.addWidget(QLabel("New layer name:")) layout2.addWidget(self.name) layout.addLayout(layout2) layout.addWidget(self.mask_widget) layout.addWidget(self.mask_widget.radius_information) layout.addWidget(self.create) self.setLayout(layout) self.mask_select.native.setDisabled(True) self.mask_widget.clip_to_mask.stateChanged.connect(self.mask_select.native.setEnabled) self.create.clicked.connect(self.create_mask)
def test_widget_options(): """Test bugfix: widget options shouldn't persist to next widget.""" E = Enum("E", ["a", "b", "c"]) choice1 = widgets.create_widget(annotation=E) choice2 = widgets.create_widget(annotation=Optional[E]) choice3 = widgets.create_widget(annotation=E) assert choice1._nullable is choice3._nullable is False assert choice2._nullable is True
def test_custom_widget(): """Test that create_widget works with arbitrary backend implementations.""" # by implementing the ValueWidgetProtocol, magicgui will know to wrap the above # widget with a widgets._bases.ValueWidget assert isinstance( widgets.create_widget(1, widget_type=MyValueWidget), ValueWidget # type:ignore )
def _get_field_from_value_type( cls, ap: AlgorithmProperty) -> typing.Union[QWidget, Widget]: if inspect.isclass(ap.value_type) and issubclass( ap.value_type, Channel): return create_widget(annotation=NapariImage, label="Image", options={}) return super()._get_field_from_value_type(ap)
def __init__(self, settings, napari_viewer, segment=None): super().__init__(settings, segment) self.napari_viewer = napari_viewer self.channels_chose = create_widget(annotation=NapariImage, label="Image", options={}) self.roi_chose = create_widget(annotation=Labels, label="ROI", options={}) self.mask_chose = create_widget(annotation=Optional[Labels], label="ROI", options={}) self.overwrite = QCheckBox("Overwrite") self.overwrite.setToolTip("If overwrite properties") self.butt_layout.insertWidget(3, self.overwrite) self.butt_layout3.insertWidget(0, QLabel("Channel:")) self.butt_layout3.insertWidget(1, self.channels_chose.native) self.butt_layout3.insertWidget(2, QLabel("ROI:")) self.butt_layout3.insertWidget(3, self.roi_chose.native) self.butt_layout3.insertWidget(4, QLabel("Mask:")) self.butt_layout3.insertWidget(5, self.mask_chose.native) self.file_names.setCurrentEnum(FileNamesEnum.No) self.file_names.setVisible(False) self.file_names_label.setVisible(False)
def test_layers_populate_immediately(make_napari_viewer): """make sure that the layers dropdown is populated upon adding to viewer""" from magicgui.widgets import create_widget labels_layer = create_widget(annotation=Labels, label="ROI") viewer = make_napari_viewer() viewer.add_labels(np.zeros((10, 10), dtype=int)) assert not len(labels_layer.choices) viewer.window.add_dock_widget(labels_layer) assert len(labels_layer.choices) == 1
def test_none_defaults(): """Make sure that an unannotated parameter with default=None is ok.""" assert widgets.create_widget(value=None).value is None def func(arg=None): return 1 assert magicgui(func)() == 1 assert str(magic_signature(func)) == str(magicgui(func).__signature__)
def test_changing_widget_attr_fails(magic_func): """Test set_widget will either update or change an existing widget.""" assert magic_func.a.value == "works" widget1 = magic_func.a assert isinstance(widget1, widgets.LineEdit) # changing it to a different type will destroy and create a new widget widget2 = widgets.create_widget(value=1, name="a") with pytest.raises(AttributeError): magic_func.a = widget2 assert magic_func.a == widget1
def test_add_at_position(labels): """Test that adding widghet with position option puts widget in the right place.""" def func(a=1, b=2, c=3): pass def get_layout_items(gui): lay = gui.native.layout() items = [ lay.itemAt(i).widget()._magic_widget.name for i in range(lay.count()) ] if labels: items = list(filter(None, items)) return items gui = magicgui(func, labels=labels) assert get_layout_items(gui) == ["a", "b", "c"] gui.insert(1, widgets.create_widget(name="new")) assert get_layout_items(gui) == ["a", "new", "b", "c"]
def test_basic_widget_attributes(): """Basic test coverage for getting/setting attributes.""" widget = widgets.create_widget(value=1, name="my_name") container = widgets.Container(labels=False) assert widget.enabled widget.enabled = False assert not widget.enabled assert not widget.visible widget.show() assert widget.visible assert widget.parent is None container.append(widget) assert widget.parent is container.native widget.parent = None assert widget.parent is None assert widget.label == "my name" widget.label = "A different label" assert widget.label == "A different label" assert widget.width < 100 widget.width = 150 assert widget.width == 150 assert widget.param_kind == inspect.Parameter.POSITIONAL_OR_KEYWORD widget.param_kind = inspect.Parameter.KEYWORD_ONLY widget.param_kind = "positional_only" assert widget.param_kind == inspect.Parameter.POSITIONAL_ONLY with pytest.raises(KeyError): widget.param_kind = "not a proper param type" with pytest.raises(TypeError): widget.param_kind = 1 assert repr(widget) == "SpinBox(value=1, annotation=None, name='my_name')" assert widget.options == { "max": 1000, "min": 0, "step": 1, "enabled": False, "visible": False, }
def _get_field(self) -> typing.Union[QWidget, Widget]: """ Get proper widget for given field type. Overwrite if would like to support new data types. """ if self.per_dimension: self.per_dimension = False prop = self.from_algorithm_property(self) self.per_dimension = True res = ListInput(prop, 3) elif not inspect.isclass(self.value_type): res = create_widget(annotation=self.value_type, options={}) elif hasattr(self.value_type, "get_object"): res = self.value_type.get_object() else: res = self._get_field_from_value_type(self) tool_tip_text = self.help_text or "" tool_tip_text += f" default value: {_pretty_print(self.default_value)}" if isinstance(res, QWidget): res.setToolTip(tool_tip_text) if isinstance(res, Widget): res.tooltip = tool_tip_text # pylint: disable=W0201 # false positive return res
def _get_field_from_value_type(cls, ap: AlgorithmProperty): if issubclass(ap.value_type, Channel): res = ChannelComboBox() res.change_channels_num(10) elif issubclass(ap.value_type, AlgorithmDescribeBase): res = SubAlgorithmWidget(ap) elif issubclass(ap.value_type, bool): res = QCheckBox() elif issubclass(ap.value_type, (float, int)): res = cls._get_numeric_field(ap) elif issubclass(ap.value_type, Enum): # noinspection PyTypeChecker res = QEnumComboBox(enum_class=ap.value_type) elif issubclass(ap.value_type, str): res = QLineEdit() elif issubclass(ap.value_type, ROIExtractionProfile): res = ProfileSelect() elif issubclass(ap.value_type, list): res = QComboBox() res.addItems(list(map(str, ap.possible_values))) else: res = create_widget(annotation=ap.value_type, options={}) return res
def test_create_widget(kwargs, expect_type): """Test that various values get turned into widgets.""" assert isinstance(widgets.create_widget(**kwargs), expect_type)
def test_custom_widget_fails(): """Test that create_widget works with arbitrary backend implementations.""" with pytest.raises(TypeError) as err: widgets.create_widget(1, widget_type=MyBadWidget) # type: ignore assert "does not implement 'WidgetProtocol'" in str(err) assert "Missing methods: {'_mgui_set_tooltip'}" in str(err)