DCC-style spinbox widgets for PySide2 and PySide6, inspired by Houdini and 3ds Max.
dcc-spinbox.mp4
- Vertical drag - Click and drag vertically on the spinbox to adjust values (3ds Max style)
- Value ladder - Middle-click to open a stepper dialog with precise step control (Houdini style)
- Modifier keys - Hold Ctrl for fine (0.1x), Alt for precision (0.01x), Shift for coarse (10x)
- ESC to cancel - Press Escape during drag to restore the original value
- Default value - Right-click on up/down buttons to reset to a configurable default
- Auto-generated steps - Step values automatically adapt to your range and decimal settings
- Cross-compatible - Works with both PySide2 and PySide6
# Install with PySide6 (recommended)
pip install qt-dcc-spinbox[pyside6]
# Or with PySide2
pip install qt-dcc-spinbox[pyside2]
# Or install without Qt dependency (if already installed)
pip install qt-dcc-spinboxgit clone https://github.com/JokerMartini/qt-dcc-spinbox.git
cd qt-dcc-spinbox
pip install -e .from qt_dcc_spinbox import SpinBox, DoubleSpinBox
# Integer spinbox
spinbox = SpinBox()
spinbox.setRange(-1000, 1000)
spinbox.setDefaultValue(0)
spinbox.setValue(100)
# Double spinbox with 3 decimal places
double_spinbox = DoubleSpinBox()
double_spinbox.setRange(-100.0, 100.0)
double_spinbox.setDecimals(3)
double_spinbox.setDefaultValue(0.0)
double_spinbox.setValue(1.5)The spinboxes work as drop-in replacements for QSpinBox and QDoubleSpinBox:
from PySide6.QtWidgets import QApplication, QVBoxLayout, QWidget
from qt_dcc_spinbox import SpinBox, DoubleSpinBox
app = QApplication([])
window = QWidget()
layout = QVBoxLayout(window)
# Add spinboxes
int_spin = SpinBox()
int_spin.setRange(0, 100)
layout.addWidget(int_spin)
float_spin = DoubleSpinBox()
float_spin.setRange(0.0, 1.0)
float_spin.setDecimals(4)
layout.addWidget(float_spin)
window.show()
app.exec()| Action | Effect |
|---|---|
| Drag vertically | Adjust value up/down |
| Ctrl + drag | Fine adjustment (0.1x speed) |
| Alt + drag | Precision adjustment (0.01x speed) |
| Shift + drag | Coarse adjustment (10x speed) |
| Middle-click | Open value ladder (stepper dialog) |
| Middle-drag horizontally | Adjust by selected step amount |
| ESC (while dragging) | Cancel and restore original value |
| Right-click on buttons | Reset to default value |
from qt_dcc_spinbox import SpinBox
spinbox = SpinBox()
# Set the default value (for right-click reset)
spinbox.setDefaultValue(50)
# Drag sensitivity is auto-calculated from range by default.
# Override with a fixed value if needed:
spinbox.setDragStepMultiplier(1.0)
# Or adjust how many pixels of drag to traverse the full range:
spinbox.setPixelsForFullRange(300) # Default is 500
# Customize the stepper dialog
spinbox.stepper.set_threshold(20) # Pixels per step (default: 10)
spinbox.stepper.set_steps([100, 50, 10, 5, 1]) # Custom step valuesBy default, the package auto-detects PySide6 first, then falls back to PySide2. To force a specific binding:
import os
os.environ["QT_BINDING"] = "pyside2" # or "pyside6"
# Must be set BEFORE importing qt_dcc_spinbox
from qt_dcc_spinbox import SpinBoxOr via environment variable:
# Windows
set QT_BINDING=pyside2 && python your_app.py
# Linux/Mac
QT_BINDING=pyside2 python your_app.pyEnhanced QSpinBox with DCC-style features.
| Method | Description |
|---|---|
setDefaultValue(value) |
Set the value to reset to on right-click |
defaultValue() |
Get the default value |
setDragStepMultiplier(value) |
Override auto drag sensitivity with a fixed value |
dragStepMultiplier() |
Get the drag sensitivity (None = auto) |
setPixelsForFullRange(pixels) |
Set pixels of drag for full range traversal (default: 500) |
stepper |
Access the StepperDialog instance |
Enhanced QDoubleSpinBox with DCC-style features. Same API as SpinBox.
The value ladder popup dialog.
| Method | Description |
|---|---|
set_steps(steps) |
Set custom step values (list of floats) |
set_threshold(pixels) |
Set horizontal drag threshold per step |
auto_generate_steps(max, decimals) |
Auto-generate steps from range |
This project uses uv for fast dependency management and testing.
# Clone and install in development mode
git clone https://github.com/JokerMartini/qt-dcc-spinbox.git
cd qt-dcc-spinbox
uv sync --extra pyside6 --extra devuv run --extra pyside6 -- python examples/demo.py# Run all tests against both bindings (Windows)
scripts\test.bat
# Or run individually
uv run --extra pyside2 --extra dev -- python -m pytest tests/ -v
uv run --extra pyside6 --extra dev -- python -m pytest tests/ -vscripts\test.bat
uv run --extra pyside2 --extra dev -- python -m pytest tests/ -v
uv run --extra pyside6 --extra dev -- python -m pytest tests/ -v
uv run --extra pyside6 -- python examples/demo.py
- Python 3.10 (pinned via
.python-versionfor PySide2 compatibility) - PySide2 >= 5.15 or PySide6 >= 6.0
MIT License - see LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Inspired by the excellent spinbox implementations in:
- SideFX Houdini - Value ladder concept
- Autodesk 3ds Max - Click-drag interaction