Reputation: 89
The following code creates a Kivy app with a single screen, MainScreen
, displaying a Label
and TextInput
object.
If you give some keyboard input when the app first loads, it prints in the console with information about which key was pressed. However, if you then click in the TextInput
object the keyboard refocuses so you can type in the TextInput
object. However, once you click back out of the TextInput
object, e.g. on the label or background, and press more keys, the same console printing operation doesn't execute; it seems that the keyboard doesn't 'defocus' from the TextInput
object.
How do I recapture keyboard focus after clicking out of a TextInput
object?
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.textinput import TextInput
kv = '''ScreenManagement:
MainScreen:
<MainScreen>:
name: "main"
BoxLayout:
Label:
text: "Label"
font_size: 20
size_hint: 0.2,0.1
TextInput
input_filter: 'float'
font_size: 20
hint_text: "Input Text"
size_hint: 0.2,0.1'''
class MainScreen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
self._keyboard.bind(on_key_down=self._on_keyboard_down)
def _keyboard_closed(self):
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
print('INFO: The key', keycode, 'has been pressed')
return True # return True to accept the key. Otherwise, it will be used by the system.
class ScreenManagement(ScreenManager):
pass
class MainApp(App):
def build(self):
return Builder.load_string(kv)
if __name__ == "__main__":
MainApp().run()
Upvotes: 3
Views: 1279
Reputation: 243945
One possible solution is to use the on_touch_down
event and reconfigure the keyboard if you press a section that does not contain a TextInput
:
class MainScreen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.config_keyboard()
def on_touch_down(self, touch):
self.isTextInput = False
def filter(widget):
for child in widget.children:
filter(child)
if isinstance(widget, TextInput) and widget.collide_point(*touch.pos):
self.isTextInput = True
widget.on_touch_down(touch)
filter(self)
if not self.isTextInput and self._keyboard is None:
self.config_keyboard()
def config_keyboard(self):
self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
self._keyboard.bind(on_key_down=self._on_keyboard_down)
def _keyboard_closed(self):
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
print('INFO: The key', keycode, 'has been pressed')
return True # return True to accept the key. Otherwise, it will be used by the system.
Upvotes: 2