diff --git a/magicgui/backends/_qtpy/widgets.py b/magicgui/backends/_qtpy/widgets.py index 96b78c3a2..4dc552bf2 100644 --- a/magicgui/backends/_qtpy/widgets.py +++ b/magicgui/backends/_qtpy/widgets.py @@ -634,7 +634,10 @@ def _mgui_set_step(self, value: float): self._readout_widget.setSingleStep(value) def _mgui_get_adaptive_step(self) -> bool: - return self._readout_widget.stepType() == QtW.QAbstractSpinBox.AdaptiveStep + return ( + self._readout_widget.stepType() + == QtW.QAbstractSpinBox.AdaptiveDecimalStepType + ) def _mgui_set_adaptive_step(self, value: bool): self._readout_widget.setStepType( diff --git a/magicgui/widgets/_bases/ranged_widget.py b/magicgui/widgets/_bases/ranged_widget.py index ef0505ba0..ae571e949 100644 --- a/magicgui/widgets/_bases/ranged_widget.py +++ b/magicgui/widgets/_bases/ranged_widget.py @@ -20,7 +20,7 @@ class RangedWidget(ValueWidget): The maximum allowable value, by default 999 (or `value` if `value` is greater than 999) step : float, optional - The step size for incrementing the value, by default 1 + The step size for incrementing the value, by default adaptive step is used """ _widget: _protocols.RangedWidgetProtocol @@ -29,8 +29,7 @@ def __init__( self, min: Union[float, _Unset] = UNSET, max: Union[float, _Unset] = UNSET, - step: float = 1, - adaptive_step: bool = True, + step: Union[float, _Unset, None] = UNSET, **kwargs, ): # sourcery skip: avoid-builtin-shadow for key in ("maximum", "minimum"): @@ -50,8 +49,12 @@ def __init__( tmp_val = float(val if val not in (UNSET, None) else 1) - self.step = step - self.adaptive_step = adaptive_step + if step is UNSET or step is None: + self.step = None + self._widget._mgui_set_step(1) + else: + self.step = cast(float, step) + self.min: float = ( cast(float, min) if min is not UNSET else builtins.min(0, tmp_val) ) @@ -99,22 +102,31 @@ def max(self, value: float): self._widget._mgui_set_max(value) @property - def step(self) -> float: - """Step size for widget values.""" + def step(self) -> Union[float, None]: + """Step size for widget values (None if adaptive step is turned on).""" + if self._widget._mgui_get_adaptive_step(): + return None return self._widget._mgui_get_step() @step.setter - def step(self, value: float): - self._widget._mgui_set_step(value) + def step(self, value: Union[float, None]): + if value is None: + self._widget._mgui_set_adaptive_step(True) + else: + self._widget._mgui_set_adaptive_step(False) + self._widget._mgui_set_step(value) @property def adaptive_step(self): """Whether the step size is adaptive.""" - return self._widget._mgui_get_adaptive_step() + return self.step is None @adaptive_step.setter def adaptive_step(self, value: bool): - self._widget._mgui_set_adaptive_step(value) + if value: + self.step = None + else: + self.step = self._widget._mgui_get_step() @property def range(self) -> Tuple[float, float]: diff --git a/tests/test_widgets.py b/tests/test_widgets.py index c93d2e2b5..4249f20a2 100644 --- a/tests/test_widgets.py +++ b/tests/test_widgets.py @@ -181,7 +181,7 @@ def test_basic_widget_attributes(): assert widget.options == { "max": 999, "min": 0, - "step": 1, + "step": None, "enabled": False, "visible": False, } @@ -581,15 +581,30 @@ def test_range_negative_value(): def test_adaptive(): + """Turn on and off adaptive step.""" + rw = widgets.SpinBox() assert rw.adaptive_step + assert rw.step is None rw.adaptive_step = False assert not rw.adaptive_step + assert rw.step == 1 + rw.step = None + assert rw.adaptive_step + assert rw.step is None + rw.step = 3 + assert not rw.adaptive_step + assert rw.step == 3 - -def test_adaptive2(): - rw = widgets.SpinBox(adaptive_step=False) + rw = widgets.SpinBox(step=2) + assert not rw.adaptive_step + assert rw.step == 2 + rw.adaptive_step = True + assert rw.adaptive_step + assert rw.step is None + rw.adaptive_step = False assert not rw.adaptive_step + assert rw.step == 2 def test_exception_range_out_of_range():