Skip to content
This repository was archived by the owner on Nov 17, 2025. It is now read-only.
This repository was archived by the owner on Nov 17, 2025. It is now read-only.

KeyError if the Scene Management widget is closed before scenes are selected #66

@psobolewskiPhD

Description

@psobolewskiPhD

Description

When you drag-n-drop a multi scene file (e.g. LIF), two widgets pop up.
The top one lets you choose to clear layers or unpack channels via checkboxes.
The bottom lets you choose scenes.
If you close the top one as spurious (whether you check something or not) and then try to load a scene, you get a key error:
KeyError: 'AICSImageIO Scene Management'

Click for code
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/Dev/napari-aicsimageio/napari_aicsimageio/core.py:198, in _get_scenes.<locals>.open_scene(item=<PyQt5.QtWidgets.QListWidgetItem object>)
    195 meta = _get_meta("", data, img)
    197 # Optionally clear layers
--> 198 if _widget_is_checked(CLEAR_LAYERS_ON_SELECT):
        CLEAR_LAYERS_ON_SELECT = 'Clear All Layers on New Scene Selection'
    199     viewer.layers.clear()
    201 # Optionally remove channel axis

File ~/Dev/napari-aicsimageio/napari_aicsimageio/core.py:131, in _widget_is_checked(widget_name='Clear All Layers on New Scene Selection')
    128 viewer = napari.current_viewer()
    130 # Get scene management widget
--> 131 scene_manager_choices_widget = viewer.window._dock_widgets[AICSIMAGEIO_CHOICES]
        viewer = Viewer(axes=AxesOverlay(visible=False, opacity=1.0, order=1000000, labels=True, colored=True, dashed=False, arrows=True), camera=Camera(center=(0.0, 0.0, 0.0), zoom=1.0, angles=(0.0, 0.0, 90.0), perspective=0.0, interactive=True), cursor=Cursor(position=(1.0, 1.0), scaled=True, size=1, style=<CursorStyle.STANDARD: 'standard'>), dims=Dims(ndim=2, ndisplay=2, last_used=0, range=((0, 2, 1), (0, 2, 1)), current_step=(0, 0), order=(0, 1), axis_labels=('0', '1')), grid=GridCanvas(stride=1, shape=(-1, -1), enabled=False), layers=[], scale_bar=ScaleBarOverlay(visible=False, opacity=1.0, order=1000000, position=<CanvasPosition.BOTTOM_RIGHT: 'bottom_right'>, colored=False, color=<class 'numpy.ndarray'> (4,) float32, ticks=True, font_size=10.0, box=False, box_color=<class 'numpy.ndarray'> (4,) float32, unit=None), text_overlay=TextOverlay(visible=False, opacity=1.0, order=1000000, position=<CanvasPosition.BOTTOM_RIGHT: 'bottom_right'>, color=<class 'numpy.ndarray'> (4,) float32, font_size=10.0, text=''), overlays=Overlays(interaction_box=InteractionBox(points=None, show=False, show_handle=False, show_vertices=False, selection_box_drag=None, selection_box_final=None, transform_start=<napari.utils.transforms.transforms.Affine object at 0x12587a1d0>, transform_drag=<napari.utils.transforms.transforms.Affine object at 0x12587a230>, transform_final=<napari.utils.transforms.transforms.Affine object at 0x12587a290>, transform=<napari.utils.transforms.transforms.Affine object at 0x12587a2f0>, allow_new_selection=True, selected_vertex=None)), help='', status='Hold <Alt> key to open plugin selection. Hold <Shift> to open files as stack.', tooltip=Tooltip(visible=False, text=''), theme='system', title='napari', mouse_over_canvas=False, mouse_move_callbacks=[<function InteractionBoxMouseBindings.initialize_mouse_events.<locals>.mouse_move at 0x12d39e950>], mouse_drag_callbacks=[<function InteractionBoxMouseBindings.initialize_mouse_events.<locals>.mouse_drag at 0x12d39e830>], mouse_double_click_callbacks=[], mouse_wheel_callbacks=[<function dims_scroll at 0x124e2e3b0>], _persisted_mouse_event={}, _mouse_drag_gen={}, _mouse_wheel_gen={}, keymap={<app_model.types._keys._keybindings.KeyBinding object at 0x12d397610>: <function InteractionBoxMouseBindings.initialize_key_events.<locals>.hold_to_lock_aspect_ratio at 0x12d39e680>, <app_model.types._keys._keybindings.KeyBinding object at 0x1246a6140>: <function InteractionBoxMouseBindings._reset_active_layer_affine at 0x12d35e5f0>, <app_model.types._keys._keybindings.KeyBinding object at 0x1246a6230>: <function InteractionBoxMouseBindings._transform_active_layer at 0x12d35e320>})
        AICSIMAGEIO_CHOICES = 'AICSImageIO Scene Management'
    132 for child in scene_manager_choices_widget.widget().children():
    133     if isinstance(child, QCheckBox):

File ~/Dev/miniforge3/envs/napari-dev/lib/python3.10/weakref.py:137, in WeakValueDictionary.__getitem__(self=<WeakValueDictionary>, key='AICSImageIO Scene Management')
    135 if self._pending_removals:
    136     self._commit_removals()
--> 137 o = self.data[key]()
        self = <WeakValueDictionary at 0x12587bd90>
        self.data = {'2021040_H33342_L929_24w_A3_tilescan.lif :: Scenes': <weakref at 0x138912250; to 'QtViewerDockWidget' at 0x13890b5b0>}
        key = 'AICSImageIO Scene Management'
    138 if o is None:
    139     raise KeyError(key)

KeyError: 'AICSImageIO Scene Management'

Expected Behavior

There should be no error. If the checkbox widget is closed then the defaults (unchecked) should be used.
Alternately—or perhaps better yet?—the widget should have an 'Apply' button to set the settings and let the widget be closed.

Reproduction

Drag and drop any multiscene file.

Environment

macOS 12.6, arm64, napari 0.4.17

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions