Kivy中TextInput失焦后on_key_down键盘事件无法触发如何解决
问题原因
- Kivy的键盘监听是独占模式:你在MainScreen初始化时通过
Window.request_keyboard拿到了键盘监听权限,绑定了按键事件 - 当你点击TextInput组件时,TextInput会主动向Window请求键盘焦点,此时你之前持有的键盘实例会触发
_keyboard_closed回调,你在这个回调里解绑了on_key_down事件,还把_keyboard变量置为None - TextInput失焦后,系统不会自动把键盘监听权限交还给MainScreen,也没有触发重新绑定的逻辑,所以你的Escape快捷键就失效了
解决方案
最适合全局快捷键场景的方案是直接绑定Window的全局按键事件,不会被组件的焦点切换影响,修改后的代码如下:
修改后的test.py
from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen from kivy.core.window import Window from kivy.config import Config Config.set('kivy', 'exit_on_escape', 0) class MainScreen(Screen): pass class UhIDontHaveIdeaForANameBecauseItsAnExampleScreen(Screen): pass class Test(App): def build(self): # 全局绑定键盘按下事件,不受组件焦点切换影响 Window.bind(on_key_down=self._on_global_key_down) return super().build() def _on_global_key_down(self, window, key, scancode, codepoint, modifiers): # 27是Escape键的标准键码 if key == 27: if self.root.current == 'Main': self.stop() Window.close() else: self.root.current = 'Main' # 返回True表示该事件已被消费,不会再向下传递给其他组件 return True Test().run()
test.kv不需要做任何修改即可正常运行。
其他可选方案
如果你需要保留组件级的键盘监听逻辑,可以在每个Screen的on_enter生命周期回调中重新请求键盘并绑定事件,在on_leave回调中解绑,但是维护成本更高,更适合单页面专属快捷键的场景。
内容的提问来源于stack exchange,提问作者Weebify
相关产品推荐
相关产品推荐

