Skip to content

visualdynamics.gui.editors

editors

Spin boxes that report a typed number only when the edit is finished.

A Qt spin box reports every keystroke by default (keyboardTracking is on unless it is turned off), so typing 50 into an overlap field reports 5 and then 50. Each report is a real edit here: it is applied to the object, the shading moves, and the panel restates the clamped value. Restating it takes the selection away in the middle of the number, so the second digit has nowhere to go, and with tracking on 50 % overlap cannot be entered at all.

So every spin box in the application commits when the edit is finished (Enter, Tab, or clicking elsewhere) or when its own arrows step it. That is Qt's keyboardTracking(False). It is a rule for the whole interface, so it is one call here instead of a setting repeated on each field.

A drag is different: it is continuous and stays live, because the gesture is the value. A half-typed number is not a value the person means.

Classes:

Name Description
SpinBox

A whole-number spin box that commits on a finished edit and

DoubleSpinBox

A decimal spin box that commits on a finished edit and brings a

Functions:

Name Description
commit_on_enter

Make these spin boxes report a value only when an edit is

commit_typed

Make every spin box under widget take the number typed into

number_box

A DoubleSpinBox over [low, high] for a settings panel.

Classes

SpinBox

SpinBox(*args, **kwargs)

Bases: _Clamping, QSpinBox

A whole-number spin box that commits on a finished edit and brings a typed value inside its range.

Qt's own spin box refuses a keystroke that would put the value out of range: with a maximum of 1638, typing 2000 stops after the third digit, and nothing says why. Here any number can be typed, and when the edit is finished it is clamped to the range and rounded, so 2000 becomes 1638. Keyboard tracking is off, as commit_on_enter sets it.

Source code in src/visualdynamics/gui/editors.py
def __init__(self, *args, **kwargs) -> None:
    super().__init__(*args, **kwargs)
    self.setKeyboardTracking(False)

DoubleSpinBox

DoubleSpinBox(*args, **kwargs)

Bases: _Clamping, QDoubleSpinBox

A decimal spin box that commits on a finished edit and brings a typed value inside its range, as SpinBox does for whole numbers.

Source code in src/visualdynamics/gui/editors.py
def __init__(self, *args, **kwargs) -> None:
    super().__init__(*args, **kwargs)
    self.setKeyboardTracking(False)

Functions:

commit_on_enter

commit_on_enter(*boxes: QAbstractSpinBox) -> None

Make these spin boxes report a value only when an edit is finished.

Parameters:

Name Type Description Default
*boxes QAbstractSpinBox

Spin boxes (QSpinBox, QDoubleSpinBox) whose valueChanged drives something. Each then reports only a finished edit or a step of its own arrows.

()
Source code in src/visualdynamics/gui/editors.py
def commit_on_enter(*boxes: QAbstractSpinBox) -> None:
    """Make these spin boxes report a value only when an edit is
    finished.

    Parameters
    ----------
    *boxes : QAbstractSpinBox
        Spin boxes (`QSpinBox`, `QDoubleSpinBox`) whose `valueChanged`
        drives something. Each then reports only a finished edit or a
        step of its own arrows.
    """
    for box in boxes:
        box.setKeyboardTracking(False)

commit_typed

commit_typed(widget: Any) -> None

Make every spin box under widget take the number typed into it, as a finished edit would.

A box that reports only finished edits (commit_on_enter) keeps its old value while the typed text stands uncommitted, and a click on a button does not finish the edit on macOS, where a button takes no focus: a size typed into Mesh Solids' box and Mesh pressed meshed at the size before it. An apply handler calls this before it reads the boxes.

Source code in src/visualdynamics/gui/editors.py
def commit_typed(widget: Any) -> None:
    """Make every spin box under `widget` take the number typed into
    it, as a finished edit would.

    A box that reports only finished edits (`commit_on_enter`) keeps
    its old value while the typed text stands uncommitted, and a click
    on a button does not finish the edit on macOS, where a button
    takes no focus: a size typed into Mesh Solids' box and Mesh
    pressed meshed at the size before it. An apply handler calls this
    before it reads the boxes.
    """
    for box in widget.findChildren(QAbstractSpinBox):
        box.interpretText()

number_box

number_box(low: float, high: float, *, value: float | None = None, decimals: int = 2, step: float | None = None, tip: str = '', suffix: str = '') -> DoubleSpinBox

A DoubleSpinBox over [low, high] for a settings panel.

The range and the places are set before the value, which is the order that keeps it: a value set first is clamped to the default range and rounded to the default two places. Like every DoubleSpinBox, it reports only a finished edit, since each report redraws a reading.

Source code in src/visualdynamics/gui/editors.py
def number_box(low: float, high: float, *, value: float | None = None,
               decimals: int = 2, step: float | None = None, tip: str = '',
               suffix: str = '') -> DoubleSpinBox:
    """A `DoubleSpinBox` over [`low`, `high`] for a settings panel.

    The range and the places are set before the value, which is the
    order that keeps it: a value set first is clamped to the default
    range and rounded to the default two places. Like every
    `DoubleSpinBox`, it reports only a finished edit, since each report
    redraws a reading.
    """
    box = DoubleSpinBox()
    box.setRange(low, high)
    box.setDecimals(decimals)
    if step is not None:
        box.setSingleStep(step)
    if value is not None:
        box.setValue(value)
    box.setToolTip(tip)
    if suffix:
        box.setSuffix(suffix)
    return box