kivymd / KivyMD

KivyMD is a collection of Material Design compliant widgets for use with Kivy, a framework for cross-platform, touch-enabled graphical applications. https://youtube.com/c/KivyMD https://twitter.com/KivyMD https://habr.com/ru/users/kivymd https://stackoverflow.com/tags/kivymd
https://kivymd.readthedocs.io
MIT License
2.2k stars 662 forks source link

Add please native int and float spinbox to uix #1537

Open o-murphy opened 1 year ago

o-murphy commented 1 year ago

Description of the Feature

Please add to uix components SpinBox widget that would accept working with native int/float value, not str as MDTextField. I must have attributes as min/max value, decimals, step and formatter to display value with defined attributes. It have looks and uses as numeric input field in html or even SpinBox in Qt library

Code and Logs

Something such as

from kivy.app import App
from kivy.lang import Builder

class MDSpinBox(MDTextField):
    def __init__(self, *args, **kwargs):
        super(MDSpinBox, self).__init__(*args, **kwargs)
        self._value: float = 0
        self.max_value: float = 0
        self.min_value: float = 100
        self.decimals: int = 2
        self.step: float = 1
        self.input_filter = 'float'

        self.prefix = ''
        self.suffix = ''

    @property
    def value(self) -> float:
        return self._value

    @value.setter
    def value(self, value: float):
        self.set_text(self, str(value))

    def keyboard_on_key_down(self, window, keycode, text, modifiers):
        if keycode == (273, 'up'):
            self.increment()
        elif keycode == (274, 'down'):
            self.decrement()
        super(MDSpinBox, self).keyboard_on_key_down(window, keycode, text, modifiers)

    def increment(self):
        self.value += self.step

    def decrement(self):
        self.value -= self.step

    def set_text(self, instance_text_field, text: str) -> None:
        if text == '':
            text = '0'
        try:
            new_decimals = int(float(text) * 10**self.decimals)
            cur_decimals = int(self.value * 10**self.decimals)
            if cur_decimals != new_decimals:
                self._value = float(text)
        except ValueError as err:
            logging.warning(err)
        formatted_text = '{:.{}f}'.format(self.value, self.decimals)
        super(MDSpinBox, self).set_text(instance_text_field, formatted_text)

    def insert_text(self, substring, from_undo=False):
        substring = substring.replace(',', '')
        if substring == '.':
            self.text = self.text[:self.cursor_index()] + substring
        else:
            super(MDSpinBox, self).insert_text(substring, from_undo)
HeaTTheatR commented 1 year ago

What is SpinBox?

o-murphy commented 1 year ago

What is SpinBox?

this image