Skip to content

Commit

Permalink
fix: fix valueChanged signals on PropertyWidget (#352)
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 authored Jul 21, 2024
1 parent 013635e commit 95117e7
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
21 changes: 12 additions & 9 deletions src/pymmcore_widgets/_property_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,17 +336,20 @@ def __init__(
self.layout().addWidget(cast(QWidget, self._value_widget))
self.destroyed.connect(self._disconnect)

def _try_update_from_core(self) -> None:
def _try_update_from_core(self) -> Any:
# set current value from core, ignoring errors
value = ""
with contextlib.suppress(RuntimeError, ValueError):
self._value_widget.setValue(self._mmc.getProperty(*self._dp))
value = self._mmc.getProperty(*self._dp)
self._value_widget.setValue(value)

# disable for any device init state besides 0 (Uninitialized)
if hasattr(self._mmc, "getDeviceInitializationState") and (
self._mmc.isPropertyPreInit(self._device_label, self._prop_name)
and self._mmc.getDeviceInitializationState(self._device_label)
):
self.setDisabled(True)
return value

# connect events and queue for disconnection on widget destroyed
def _on_core_change(self, dev_label: str, prop_name: str, new_val: Any) -> None:
Expand All @@ -355,13 +358,13 @@ def _on_core_change(self, dev_label: str, prop_name: str, new_val: Any) -> None:
self._value_widget.setValue(new_val)

def _on_value_widget_change(self, value: Any) -> None:
if not self._updates_core:
return
try:
self._mmc.setProperty(self._device_label, self._prop_name, value)
except (RuntimeError, ValueError):
# if there's an error when updating mmcore, reset widget value to mmcore
self._try_update_from_core()
if self._updates_core:
try:
self._mmc.setProperty(self._device_label, self._prop_name, value)
except (RuntimeError, ValueError):
# if there's an error when updating mmcore, reset widget value to mmcore
value = self._try_update_from_core()
self.valueChanged.emit(value)

def _disconnect(self) -> None:
with contextlib.suppress(RuntimeError):
Expand Down
13 changes: 11 additions & 2 deletions tests/test_prop_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def _assert_equal(a, b):


@pytest.mark.parametrize("dev, prop", dev_props)
def test_property_widget(dev, prop, qtbot):
def test_property_widget(dev, prop, qtbot) -> None:
wdg = PropertyWidget(dev, prop, mmcore=CORE)
qtbot.addWidget(wdg)
if CORE.isPropertyReadOnly(dev, prop) or prop in (
Expand Down Expand Up @@ -83,7 +83,16 @@ def test_property_widget(dev, prop, qtbot):
_assert_equal(wdg.value(), start_val)


def test_reset(global_mmcore, qtbot):
def test_prop_widget_signals(global_mmcore: CMMCorePlus, qtbot):
wdg = PropertyWidget("Camera", "Binning", connect_core=False)
qtbot.addWidget(wdg)
assert wdg.value() == "1"
with qtbot.waitSignal(wdg.valueChanged, timeout=1000):
wdg._value_widget.setValue(2)
assert wdg.value() == "2"


def test_reset(global_mmcore: CMMCorePlus, qtbot) -> None:
wdg = PropertyWidget("Camera", "Binning", mmcore=global_mmcore)
qtbot.addWidget(wdg)
global_mmcore.loadSystemConfiguration()
Expand Down

0 comments on commit 95117e7

Please sign in to comment.