Skip to content

visualdynamics.gui.editors

editors

When a typed number counts as meant.

A Qt spin box reports every keystroke by default — keyboardTracking is on unless it is turned off — so typing 50 into an overlap field emits 5 first and 50 second. That is not merely noisy. Each report is a real edit here: it lands on the object, the shading moves, the panel restates the clamped value, and restating it takes the selection away mid-number, so the second digit has nowhere to go. The field fights the person typing into it, and 50% overlap cannot be entered at all (Brandon, 2026-08-27; the same on frame length).

So every spin box in the application commits when the edit is finished — Enter, Tab, clicking elsewhere — or when its own arrows step it. That is Qt's keyboardTracking(False), and it is a rule about the whole interface rather than a property of any one field, which is why it is a call here and not nine scattered ones.

This is not in tension with principle 8, which puts the effort where the user is waiting: a drag is continuous and must stay live, because the gesture is the value. Typing is not continuous — the half-typed number is not a number the person means, and treating it as one is the bug.

Classes:

Name Description
SpinBox

A whole-number box that commits on Enter and clamps what it is

DoubleSpinBox

A decimal box that commits on Enter and clamps what it is

Functions:

Name Description
commit_on_enter

Stop these editors reporting a value the user is still typing.

Classes

SpinBox

SpinBox(*args, **kwargs)

Bases: _Clamping, QSpinBox

A whole-number box that commits on Enter and clamps what it is given. See _Clamping and commit_on_enter.

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 box that commits on Enter and clamps what it is given. See _Clamping and commit_on_enter.

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

Stop these editors reporting a value the user is still typing.

Parameters:

Name Type Description Default
*boxes QAbstractSpinBox

Spin boxes — QSpinBox, QDoubleSpinBox — whose valueChanged drives something. Each will report only on 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:
    """Stop these editors reporting a value the user is still typing.

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