Skip to content

Commit

Permalink
feat: add stepType to largeInt spinbox (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 authored Aug 6, 2023
1 parent 0407fdc commit 7b964be
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
36 changes: 32 additions & 4 deletions src/superqt/spinbox/_intspin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import math
from enum import Enum

from qtpy.QtCore import QSize, Qt, Signal
Expand Down Expand Up @@ -42,6 +43,9 @@ def __init__(self, parent=None) -> None:
self._minimum: int = 0
self._maximum: int = 2**64 - 1
self._single_step: int = 1
self._step_type: QAbstractSpinBox.StepType = (
QAbstractSpinBox.StepType.DefaultStepType
)
self._pending_emit = False
validator = _AnyIntValidator(self)
self.lineEdit().setValidator(validator)
Expand Down Expand Up @@ -78,7 +82,13 @@ def singleStep(self):
def setSingleStep(self, step):
self._single_step = int(step)

# TODO: add prefix/suffix/stepType
def setStepType(self, stepType: QAbstractSpinBox.StepType) -> None:
self._step_type = stepType

def stepType(self) -> QAbstractSpinBox.StepType:
return self._step_type

# TODO: add prefix/suffix

# ############### QtOverrides #######################

Expand All @@ -102,13 +112,16 @@ def keyPressEvent(self, e) -> None:
return super().keyPressEvent(e)

def stepBy(self, steps: int) -> None:
step = self._single_step
old = self._value
e = _EmitPolicy.EmitIfChanged
if self._pending_emit:
self._interpret(_EmitPolicy.NeverEmit)
if self._value != old:
e = _EmitPolicy.AlwaysEmit
if self._step_type == QAbstractSpinBox.StepType.AdaptiveDecimalStepType:
step = self._calculate_adaptive_decimal_step(steps)
else:
step = self._single_step
self._setValue(self._bound(self._value + (step * steps)), e)

def stepEnabled(self):
Expand Down Expand Up @@ -164,13 +177,28 @@ def _interpret(self, policy):
v = int(text)
self._setValue(v, policy)

def _editor_text_changed(self, t):
def _editor_text_changed(self, t: str) -> None:
if self.keyboardTracking():
self._setValue(int(t), _EmitPolicy.EmitIfChanged)
try:
self._setValue(int(t), _EmitPolicy.EmitIfChanged)
except ValueError:
pass
self.lineEdit().setFocus()
self._pending_emit = False
else:
self._pending_emit = True

def _bound(self, value):
return max(self._minimum, min(self._maximum, value))

def _calculate_adaptive_decimal_step(self, steps: int) -> int:
abs_value = abs(self._value)
if abs_value < 100:
return 1

value_negative = self._value < 0
steps_negative = steps < 0
sign_compensation = 0 if value_negative == steps_negative else 1

log = int(math.log10(abs_value - sign_compensation)) - 1
return int(math.pow(10, log))
13 changes: 13 additions & 0 deletions tests/test_large_int_spinbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,16 @@ def test_keyboard_tracking(qtbot):
sb.lineEdit().setText("25")
assert sb._pending_emit is False
assert sgnl.args == [25]


def test_large_spinbox_step_type(qtbot):
sb = QLargeIntSpinBox()
qtbot.addWidget(sb)
sb.setMaximum(1_000_000_000)
sb.setStepType(sb.StepType.AdaptiveDecimalStepType)
sb.setValue(1_000_000)
sb.stepBy(1)
assert sb.value() == 1_100_000
sb.setStepType(sb.StepType.DefaultStepType)
sb.stepBy(1)
assert sb.value() == 1_100_001

0 comments on commit 7b964be

Please sign in to comment.