键盘输入事件被 TextInput 窃听?

Posted

技术标签:

【中文标题】键盘输入事件被 TextInput 窃听?【英文标题】:Keyboard input event bugged with TextInput? 【发布时间】:2021-10-25 17:24:38 【问题描述】:

基本上,我一直在开发具有多个屏幕的 Kivy 应用程序,并且我正在尝试制作它,以便在按下退出按钮时将您带回主屏幕。事情进展顺利,因为我关注了this question's answer,除了当我关注 TextInput 小部件并取消焦点时,不再调用转义键快捷方式,或者更具体地说,on_key_down 事件。

有谁知道怎么回事?任何帮助将不胜感激!

编辑:这是我的代码,缩短和简化:

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):
    def __init__(self, **kwargs):
        super(Screen, self).__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(keycode[1])
        if keycode[1] == 'escape':
            if App.get_running_app().root.current == 'Main':
                App.get_running_app().stop()
                Window.close()
            else:
                App.get_running_app().root.current = 'Main'

class UhIDontHaveIdeaForANameBecauseItsAnExampleScreen(Screen):
    pass
     
class Test(App):    
    pass

Test().run()

test.kv

ScreenManager:
    MainScreen:
        id: Main
    UhIDontHaveIdeaForANameBecauseItsAnExampleScreen:
        id: Settings
    
<MainScreen>:
    name: 'Main'
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: 'idk just press it bruh'
        Button:
            id: butt
            text: 'no clue'
            on_release: app.root.current = 'NoClue'

<UhIDontHaveIdeaForANameBecauseItsAnExampleScreen>:
    name: 'NoClue'
    
    TextInput:
        size_hint: 0.4, 0.1
        pos_hint: 'center_x': 0.5, 'center_y': 0.5

【问题讨论】:

你能分享你的代码并描述你尝试了什么以及你想要什么 我用简化代码编辑了我的问题,你可以在那里查看! 【参考方案1】:

您在创建主屏幕时将其绑定到监听键盘,但是当您聚焦 Textinput 时,kivy 会自动将键盘绑定到 textinput 所以MainScreen 中的_on_keyboard_down 方法有很多解决方案,但我们需要再次将主屏幕绑定到键盘,以便_on_keyboard_down 再次开始听键盘,我们可以在@ 内执行此操作987654324@ 和_on_textinput_focused 方法如下

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.config import Config
from kivy.uix.textinput import TextInput

Config.set('kivy', 'exit_on_escape', 0)


class MainScreen(Screen):
    def __init__(self, **kwargs):
        super(Screen, self).__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(keycode[1])
        if keycode[1] == 'escape':
            if App.get_running_app().root.current == 'Main':
                App.get_running_app().stop()
                Window.close()
            else:
                App.get_running_app().root.current = 'Main'

class UhIDontHaveIdeaForANameBecauseItsAnExampleScreen(Screen):
    pass


class TextField(TextInput):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def _on_textinput_focused(self, instance, value, *largs):
        print(instance.focus)
        # test if the text input is focused 
        if not instance.focus:
            app=App.get_running_app()
            app.root.ids.Main._keyboard = Window.request_keyboard(app.root.ids.Main._keyboard_closed, self)
            app.root.ids.Main._keyboard.bind(on_key_down=app.root.ids.Main._on_keyboard_down)

class Test(App):
    pass


Test().run()


并在 kv 文件中使用 TextField 像这样


ScreenManager:
    MainScreen:
        id: Main
    UhIDontHaveIdeaForANameBecauseItsAnExampleScreen:
        id: Settings
    
<MainScreen>:
    name: 'Main'
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: 'idk just press it bruh'
        Button:
            id: butt
            text: 'no clue'
            on_release: app.root.current = 'NoClue'
<UhIDontHaveIdeaForANameBecauseItsAnExampleScreen>:
    name: 'NoClue'

    TextField:
        size_hint: 0.4, 0.1
        pos_hint: 'center_x': 0.5, 'center_y': 0.5
<TextField>:

【讨论】:

以上是关于键盘输入事件被 TextInput 窃听?的主要内容,如果未能解决你的问题,请参考以下文章

TextInput

TextInput组件的常用属性

WPF学习第十六章 键盘输入

事件类型--键盘与文本事件

WPF学习第十六章 键盘输入

平板电脑输入面板不会引起TextInput事件?