Kivy: How to start text on the right side in TextInput?

When I type MyFloatInputTextInput, then the text starts on rightthe TextInput side, it works fine
but I set the MyFloatInputTextInput value from .py, then started on the left side. It does not appear on the right side.
Can someone tell me what is wrong with the code?

test.py

import kivy

from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.uix.textinput import TextInput

Window.clearcolor = (0.5, 0.5, 0.5, 1)
Window.size = (400, 100)


class MyFloatInput(TextInput):

    def __init__(self, **kwargs):
        super(MyFloatInput, self).__init__(**kwargs)
        self.multiline = False

    def right_adjust(self, text):
        max_width = self.width - self.padding[0] - self.padding[2]
        new_text = text
        text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
        while text_width < max_width:
            new_text = ' ' + new_text
            text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
        while text_width >= max_width:
            if new_text[0] != ' ':
                break
            else:
                new_text = new_text[1:]
                text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
        return new_text

    def delete_selection(self, from_undo=False):
        if not self._selection:
            return
        cr = self.cursor[1]
        initial_len = len(self._lines[cr])
        a, b = self._selection_from, self._selection_to
        if a > b:
            a, b = b, a
        super(MyFloatInput, self).delete_selection(from_undo=from_undo)
        cur_text = self._lines[cr]
        super(MyFloatInput, self)._refresh_text(self.right_adjust(cur_text))
        final_len = len(self._lines[cr])
        self.cursor = self.get_cursor_from_index(final_len - (initial_len - b))

    def do_backspace(self, from_undo=False, mode='bkspc'):
        cc, cr = self.cursor
        initial_len = len(self._lines[cr])
        super(MyFloatInput, self).do_backspace(from_undo=from_undo, mode=mode)
        cc, cr = self.cursor
        cur_text = self._lines[cr]
        super(MyFloatInput, self)._refresh_text(self.right_adjust(cur_text))
        final_len = len(self._lines[cr])
        self.cursor = self.get_cursor_from_index(final_len - (initial_len-cc) + 1)

    def insert_text(self, the_text, from_undo=False):
        cc, cr = self.cursor
        cur_text = self._lines[cr]
        initial_len = len(cur_text)
        new_text = self.right_adjust(cur_text[:cc] + the_text + cur_text[cc:])
        try:
            num = float(new_text) # throw exception if new_text is invalid float
        except ValueError:
            return
        self._lines[cr] = ''
        super(MyFloatInput, self).insert_text(new_text, from_undo=from_undo)
        final_len = len(self._lines[cr])
        self.cursor = self.get_cursor_from_index(final_len - (initial_len-cc))

    def set_right_adj_text(self, text):
        num = float(text)  # throws exception if text is invalid float
        self._refresh_text(self.right_adjust(text))

    def on_text(self, instance, text):
        #num = float(text)  # throws exception if text is invalid float
        self._refresh_text(self.right_adjust(text))

class Testing(Screen):

    def __init__(self, **kwargs):
        super(Testing, self).__init__(**kwargs)
        Clock.schedule_once(lambda dt: setattr(self.test, 'text', str(100)))

class Test(App):

    def build(self):
        self.root = Builder.load_file('test.kv')
        return self.root


if __name__ == '__main__':
    Test().run()

test.kv

Testing:
    test:test
    BoxLayout:
        orientation: "vertical"
        padding : 20, 20

        BoxLayout:
            orientation: "horizontal"
            padding: 10, 10
            spacing: 10, 10
            size_hint_x: .6

            Label:
                text: "No."
                text_size: self.size
                valign: 'middle'
                size_hint_x: .2

            MyFloatInput:
                size_hint_x: .6
                id : test
+4
source share
2 answers

I made significant changes to the class MyFloatInput. Now he no longer needs import string. Now it handles the removal of the selection, and now you can set the text from the .py file using the method set_right_adj_text("some text"). Here is an improved class:

class MyFloatInput(TextInput):

    def __init__(self, **kwargs):
        super(MyFloatInput, self).__init__(**kwargs)
        self.multiline = False

    def right_adjust(self, text):
        max_width = self.width - self.padding[0] - self.padding[2]
        new_text = text
        text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
        while text_width < max_width:
            new_text = ' ' + new_text
            text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
        while text_width >= max_width:
            if new_text[0] != ' ':
                break
            else:
                new_text = new_text[1:]
                text_width = self._get_text_width(new_text, self.tab_width, self._label_cached)
        return new_text

    def on_size(self, instance, value):
        super(MyFloatInput, self).on_size(instance, value)
        if len(self._lines) == 0:
            return True
        cc, cr = self.cursor
        cur_text = self._lines[cr]
        initial_len = len(cur_text)
        super(MyFloatInput, self)._refresh_text(self.right_adjust(cur_text))
        final_len = len(self._lines[cr])
        self.cursor = self.get_cursor_from_index(final_len - (initial_len - cc))
        return True

    def delete_selection(self, from_undo=False):
        if not self._selection:
            return
        cr = self.cursor[1]
        initial_len = len(self._lines[cr])
        a, b = self._selection_from, self._selection_to
        if a > b:
            a, b = b, a
        super(MyFloatInput, self).delete_selection(from_undo=from_undo)
        cur_text = self._lines[cr]
        super(MyFloatInput, self)._refresh_text(self.right_adjust(cur_text))
        final_len = len(self._lines[cr])
        self.cursor = self.get_cursor_from_index(final_len - (initial_len - b))

    def do_backspace(self, from_undo=False, mode='bkspc'):
        cc, cr = self.cursor
        initial_len = len(self._lines[cr])
        super(MyFloatInput, self).do_backspace(from_undo=from_undo, mode=mode)
        cc, cr = self.cursor
        cur_text = self._lines[cr]
        super(MyFloatInput, self)._refresh_text(self.right_adjust(cur_text))
        final_len = len(self._lines[cr])
        self.cursor = self.get_cursor_from_index(final_len - (initial_len-cc) + 1)

    def insert_text(self, the_text, from_undo=False):
        cc, cr = self.cursor
        cur_text = self._lines[cr]
        initial_len = len(cur_text)
        new_text = self.right_adjust(cur_text[:cc] + the_text + cur_text[cc:])
        try:
            num = float(new_text) # throw exception if new_text is invalid float
        except ValueError:
            return
        self._lines[cr] = ''
        super(MyFloatInput, self).insert_text(new_text, from_undo=from_undo)
        final_len = len(self._lines[cr])
        self.cursor = self.get_cursor_from_index(final_len - (initial_len-cc))

    def set_right_adj_text(self, text):
        num = float(text)  # throws exception if text is invalid float
        self._refresh_text(self.right_adjust(text))
+2
source

, , , TextInput. , TextInput. MyFloatInput:

import string

class MyFloatInput(TextInput):

    def __init__(self, **kwargs):
        super(MyFloatInput, self).__init__(**kwargs)
        self.multiline = False

    def insert_text(self, theText, from_undo=False):
        if theText not in string.digits and theText != '.':
            return
        if '.' in self.text and theText == '.':
            return

        maxWidth = self.width - self.padding[0] - self.padding[2]
        cc, cr = self.cursor
        curText = self._lines[cr]
        new_text = curText[:cc] + theText + curText[cc:]
        textWidth = self._get_text_width(new_text, self.tab_width, self._label_cached)
        while textWidth < maxWidth:
            new_text = ' ' + new_text
            textWidth = self._get_text_width(new_text, self.tab_width, self._label_cached)
        while textWidth >= maxWidth:
            if new_text[0] != ' ':
                break
            else:
                new_text = new_text[1:]
                textWidth = self._get_text_width(new_text, self.tab_width, self._label_cached)
        self._lines[cr] = ''
        self.cursor = (0,cr)
        super(MyFloatInput, self).insert_text(new_text, from_undo=from_undo)

, , float. , .py TextInput .kv :

        MyFloatInput:
            size_hint_x: .2

, , __init__ multiline False. , _, , TextInput .

+3

Source: https://habr.com/ru/post/1694864/


All Articles