2025-03-07 08:03:18 +01:00

103 lines
3.2 KiB
Python

# SPDX-FileCopyrightText: © 2022-2023 Wojciech Trybus <wojtryb@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
from typing import Any, List, Final, Optional, TypeVar, Generic, Protocol
from PyQt5.QtWidgets import QDoubleSpinBox, QComboBox, QSpinBox, QWidget
from ..field import Field
from .config_based_widget import ConfigBasedWidget
F = TypeVar("F", bound=float)
class SpinBox(Protocol, Generic[F]):
"""Representation of both Qt spinboxes as one generic class."""
def value(self) -> F: ...
def setValue(self, val: F) -> None: ...
class ConfigSpinBox(ConfigBasedWidget[F]):
"""
Wrapper of SpinBox linked to a configutation field.
Based on QSpinBox or QDoubleSpinBox depending on the config type.
Works only for fields of type: `int` or `float`.
"""
def __init__(
self,
config_field: Field[F],
parent: Optional[QWidget] = None,
pretty_name: Optional[str] = None,
step: F = 1,
max_value: F = 100,
) -> None:
super().__init__(config_field, parent, pretty_name)
self._step = step
self._max_value = max_value
self._spin_box = self._init_spin_box()
self.widget: Final[SpinBox[F]] = self._spin_box
self.reset()
def read(self) -> F:
"""Return the current value of the spinbox widget."""
return self._spin_box.value()
def set(self, value: F):
"""Replace the value of the spinbox widget with passed one."""
self._spin_box.setValue(value)
def _init_spin_box(self) -> SpinBox:
"""Return the spinbox widget of type based on config field type."""
spin_box: QDoubleSpinBox = {int: QSpinBox, float: QDoubleSpinBox}[
type(self.config_field.default)]()
spin_box.setMinimumWidth(90)
spin_box.setObjectName(self.config_field.name)
spin_box.setMinimum(0)
spin_box.setSingleStep(self._step)
spin_box.setMaximum(self._max_value)
return spin_box
class ConfigComboBox(ConfigBasedWidget[str]):
"""
Wrapper of Combobox linked to a configutation field.
Works only for fields of type: `str`.
"""
def __init__(
self,
config_field: Field[str],
parent: Optional[QWidget] = None,
pretty_name: Optional[str] = None,
allowed_values: List[Any] = [],
) -> None:
super().__init__(config_field, parent, pretty_name)
self._allowed_values = allowed_values
self._combo_box = self._init_combo_box()
self.widget: Final[QComboBox] = self._combo_box
self.reset()
def reset(self) -> None:
"""Update allowed values of the combobox and pick a default one."""
self._combo_box.clear()
self._combo_box.addItems(self._allowed_values)
self.set(self.config_field.read())
def read(self) -> str:
"""Return the current value of the ComboBox."""
return self._combo_box.currentText()
def set(self, value: str):
"""Replace the value of the ComboBox with passed one."""
return self._combo_box.setCurrentText(value)
def _init_combo_box(self) -> QComboBox:
"""Return the spinbox widget."""
combo_box = QComboBox()
combo_box.setObjectName(self.config_field.name)
return combo_box