Pappy38
Pappy38

Reputation: 16

KivyMD TextField decorator Issues

I am creating a Custom KivyMD TextField class with a decorator in order to solve the bug in my App where moving from one text field to another on tapping the next text field the android keyboard disappears. Making have to tap outside/neutral part of screen first before touching the textfield before the keyboard appears again.

This is my code:

from kivy.core.window import Window
from kivy.lang import Builder
from kivy.clock import Clock
from kivymd.app import MDApp
from kivymd.uix.textfield import MDTextField


KV = '''

<CustomMDTextField>:


MDScreen:
    MDBoxLayout:
        orientation: "vertical"
        spacing: "40sp"
        adaptive_height: True
        size_hint_x: .8
        pos_hint: {"center_x": .5, "center_y": .5}
        MDLabel:
            id: head_label
            text: "Empty"
            font_size: "70sp"
            pos_hint: {"center_x": .8, "center_y": .5}
        CustomMDTextField:
            id: text_input_field
            font_size: "50sp"
            hint_text: "Input text only"
            helper_text: "To test Android text keyboard"
            helper_text_mode: "persistent"
            input_type: "text"
            on_text: app.update_label_text()
            pos_hint: {"center_x": .5, "center_y": .5}
            size_hint_x: .5
        CustomMDTextField:
            id: num_input_field
            font_size: "50sp"
            hint_text: "Input numbers only"
            helper_text: "To test Android digit keyboard"
            helper_text_mode: "persistent"
            input_type: "number"
            on_text: app.update_label_num()
            pos_hint: {"center_x": .5, "center_y": .5}
            size_hint_x: .5

'''


Window.softinput_mode = "below_target"


class CustomMDTextField(MDTextField):

    def __init__(self, *args, **kwargs):
        super().__init__(**kwargs)

    def on_focus(self, instance_text_field, focus: bool, *args) -> None:
        if focus:
            Clock.schedule_once(self.create_keyboard, .1)
        else:
            self.hide_keyboard()

    def create_keyboard(self, *args):
        self.show_keyboard()

    def remove_focus_decorator(self, function):
        def wrapper(touch):
            if not self.collide_point(*touch.pos):
                self.focus = False
            function(touch)
        return wrapper

    @remove_focus_decorator
    def on_touch_down(self, touch):
        super().on_touch_down(touch)


class KeyBoardApp(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # self.screen = Builder.load_string(KV)

    def build(self):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Green"
        self.screen = Builder.load_string(KV)
        self.screen.ids.text_input_field.bind(
            on_text_validate=self.update_label_text
        )
        self.screen.ids.num_input_field.bind(
            on_text_validate=self.update_label_num
        )
        return self.screen

    def update_label_text(self, *args):
        self.screen.ids.head_label.text = self.screen.ids.text_input_field.text

    def update_label_num(self, *args):
        self.screen.ids.head_label.text = self.screen.ids.num_input_field.text


KeyBoardApp().run()

When I run it, I am getting TypeError: CustomMDTextField.remove_focus_decorator() missing 1 required positional argument: 'function'

And I understand the 'function' argument is the on_touch_down function under the decorator(from my understanding of decorators), so i don't understand why it gives this error.

Upvotes: 0

Views: 14

Answers (0)

Related Questions