Search code examples
pythonkivykivy-language

How to only accept two numbers in the Texinputfield?


I want to only accept two numbers in my Textinput. I know how to only accept numbers, and i know how to only accept two letters, but not how to do both.

This code only accept to letters:

TextInput:
    multiline: False
    input_filter: lambda text, from_undo: text[:2 - len(self.text)]

And this code only accept numbers:

TextInput:
    multiline: False
    input_filter: "int"

But when i try something like:

TextInput:
    multiline: False
    input_filter: "int", lambda text, from_undo: text[:2 - 
    len(self.text)]

I get this error:

TypeError: 'tuple' object is not callable

Solution

  • Far as I know, you cannot do what you want in this way. But you can use a NumericInput, this class will use the TextInput and will handle your limits. I hope this can help you, It's a little bit different of your original idea, but solves the problem.

    So try de follow:

    main.py file

    from kivy.app import App
    from kivy.base import Builder
    from kivy.properties import NumericProperty
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.textinput import TextInput
    from kivy.uix.screenmanager import ScreenManager
    
    
    class NumericInput(TextInput):
        min_value = NumericProperty(None)
        max_value = NumericProperty(None)
    
        def __init__(self, *args, **kwargs):
            TextInput.__init__(self, *args, **kwargs)
            self.input_filter = 'int' # The type of your filter
            self.multiline = False
    
        def insert_text(self, string, from_undo=False):
            new_text = self.text + string
    
            if new_text != "" and len(new_text) < 3:
                try:
                    # Will try convert the text to a int and compare, if it's not a number
                    # It will throw a exception and will not append the text into the input
    
                    # If the value is between the values and is a int
                    if self.min_value <= int(new_text) <= self.max_value:
                        TextInput.insert_text(self, string, from_undo=from_undo)
                except ValueError as e: # Just cannot convert to a `int`
                    pass
    
    
    
    class BoundedLayout(BoxLayout):
        pass
    
    
    presentation = Builder.load_file("gui.kv")
    class App(App):
        def build(self):
            return BoundedLayout()
    
    if __name__ == '__main__':
        App().run()
    

    gui.kv file

    #:kivy 1.0
    
    <BoundedLayout>:
      orientation: 'horizontal'
      Label:
        text: 'Value'
      NumericInput:
        min_value : 0 # your smaller value, can be negative too
        max_value : 99 # Here goes the max value
        hint_text : 'Enter values between {} and {}'.format(self.min_value, self.max_value)