From 667f297e6e77274a83250227cba64f467bc21752 Mon Sep 17 00:00:00 2001 From: dario Date: Tue, 5 May 2026 12:45:54 +0200 Subject: [PATCH] added guard to fix runtime error during mda events that was calling on_property_changed with an empty device label --- src/pymmcore_widgets/control/_presets_widget.py | 2 ++ tests/test_presets_widget.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/pymmcore_widgets/control/_presets_widget.py b/src/pymmcore_widgets/control/_presets_widget.py index e2496a703..dc4b97b5c 100644 --- a/src/pymmcore_widgets/control/_presets_widget.py +++ b/src/pymmcore_widgets/control/_presets_widget.py @@ -140,6 +140,8 @@ def _on_cfg_set(self, group: str, preset: str) -> None: @Slot(str, str, object) def _on_property_changed(self, device: str, property: str, value: str) -> None: + if not device: + return if (device, property) not in self.dev_prop: if self._mmc.getDeviceType(device) != DeviceType.StateDevice: return diff --git a/tests/test_presets_widget.py b/tests/test_presets_widget.py index 7528a633f..e26a3a6d0 100644 --- a/tests/test_presets_widget.py +++ b/tests/test_presets_widget.py @@ -76,3 +76,18 @@ def test_preset_widget(qtbot: QtBot, global_mmcore: CMMCorePlus) -> None: global_mmcore.deleteConfigGroup("Camera") assert "Camera" not in global_mmcore.getAvailableConfigGroups() + + +def test_preset_widget_ignores_empty_device( + qtbot: QtBot, global_mmcore: CMMCorePlus +) -> None: + """propertyChanged with empty device label must not raise RuntimeError. + + The C++ core can emit propertyChanged("", ...) for internal state changes + with no associated device (e.g. during MDA teardown). The widget must + guard against calling getDeviceType("") in that case. + """ + wdg = PresetsWidget("Channel") + qtbot.addWidget(wdg) + # Should not raise RuntimeError: No device with label "" + global_mmcore.events.propertyChanged.emit("", "State", "1")