Skip to content

Commit 4cdb6b9

Browse files
committed
Fix KeypointStore not initializing when layers load before widget
1 parent 5511f7d commit 4cdb6b9

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

src/napari_deeplabcut/_widgets.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,61 @@ def __init__(self, napari_viewer):
697697
# (Of course this will be a problem if we start using it everywhere so do not reuse lightly)
698698
QTimer.singleShot(10, self.silently_dock_matplotlib_canvas)
699699

700+
# Retroactively initialize KeypointStores for Points layers that were
701+
# added before this widget was fully initialized (timing issue where
702+
# on_insert never fires for pre-existing layers).
703+
self._init_retry_count = 0
704+
QTimer.singleShot(1000, self._retroactive_store_init)
705+
706+
def _retroactive_store_init(self):
707+
self._init_retry_count += 1
708+
if self._stores:
709+
return
710+
has_points = any(
711+
isinstance(l, Points) and l.metadata.get("header")
712+
for l in self.viewer.layers
713+
)
714+
if not has_points:
715+
if self._init_retry_count < 10:
716+
QTimer.singleShot(1000, self._retroactive_store_init)
717+
return
718+
# Populate _images_meta from Image layers (normally done by on_insert)
719+
for layer in self.viewer.layers:
720+
if isinstance(layer, Image) and layer.metadata.get("root"):
721+
self._images_meta.update(
722+
{
723+
"paths": layer.metadata.get("paths"),
724+
"shape": layer.level_shapes[0],
725+
"root": layer.metadata["root"],
726+
"name": layer.name,
727+
}
728+
)
729+
for layer in self.viewer.layers:
730+
if isinstance(layer, Points) and layer.metadata.get("header"):
731+
store = keypoints.KeypointStore(self.viewer, layer)
732+
self._stores[layer] = store
733+
if root := layer.metadata.get("root"):
734+
update_save_history(root)
735+
layer.metadata["controls"] = self
736+
layer.text.visible = False
737+
layer.bind_key("M", self.cycle_through_label_modes)
738+
layer.bind_key("F", self.cycle_through_color_modes)
739+
func = partial(_paste_data, store=store)
740+
layer._paste_data = MethodType(func, layer)
741+
layer.add = MethodType(keypoints._add, store)
742+
layer.events.add(query_next_frame=Event)
743+
layer.events.query_next_frame.connect(store._advance_step)
744+
layer.bind_key("Shift-Right", store._find_first_unlabeled_frame)
745+
layer.bind_key("Shift-Left", store._find_first_unlabeled_frame)
746+
layer.bind_key("Down", store.next_keypoint, overwrite=True)
747+
layer.bind_key("Up", store.prev_keypoint, overwrite=True)
748+
layer.face_color_mode = "cycle"
749+
self._form_dropdown_menus(store)
750+
self._radio_box.setEnabled(True)
751+
self._color_grp.setEnabled(True)
752+
self._trail_cb.setEnabled(True)
753+
self._show_traj_plot_cb.setEnabled(True)
754+
700755
def _ensure_mpl_canvas_docked(self) -> None:
701756
"""
702757
Dock the Matplotlib canvas as a napari dock widget, exactly once,
@@ -1225,6 +1280,9 @@ def on_insert(self, event):
12251280

12261281
return
12271282

1283+
if not layer.metadata.get("header"):
1284+
return
1285+
12281286
if layer.metadata.get("tables", ""):
12291287
self._keypoint_mapping_button.show()
12301288

0 commit comments

Comments
 (0)