Reputation: 16
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