【问题标题】:Kivy - How does one get the correct character from a keypress with/without modifiers?Kivy - 如何从带/不带修饰符的按键中获得正确的字符?
【发布时间】:2016-11-15 17:49:20
【问题描述】:

在 Python 中使用 Kivy,如何从带有/不带有修饰符的按键中获取正确的字符?

我不想使用 kivy.uix.textinput.TextInput。我只想知道用户想输入什么字符。

我可以使用从kivy.core.window.Window.request_keyboard() 返回的键盘来获取当前按下的键的扫描码,但这不考虑修饰符,即 shift 键。

显然,我可以自己编写一些东西来检查是否同时按下了 shift,如果是,则将其转换为相应的字符。但是这个解决方案是不可移植的,除非每个人的键盘都和我的键盘布局一样。

有没有办法根据系统键盘映射得到正确的字符?

我快速查看了TextInput source,但看不到任何对 request_keyboard() 的调用。

不要告诉我使用 TextInput。

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    你可以试试这个code。它按名称为您提供修饰符(ShiftAltCrtl 等)

    如果您希望您的小部件监听所有输入,而不管其他小部件是否有焦点,只需更改以下内容:

    def _keyboard_closed(self):
            print('My keyboard have been closed!')
            self._keyboard.unbind(on_key_down=self._on_keyboard_down)
            self._keyboard = None
    

    到:

    def _keyboard_closed(self):
            pass
    

    这将避免小部件释放键盘,因此它会一直监听所有内容。

    TextInput 在每次焦点更改为 true 时调用 FocusBehaviour 的 _ensure_keyboard() 方法中的 request_keyboard()

    def _on_focus(self, instance, value, *largs):
            if self.keyboard_mode == 'auto':
                if value:
                    self._bind_keyboard()
            ....
    
    def _bind_keyboard(self):
            self._ensure_keyboard()
            ....
    
    def _ensure_keyboard(self):
            if self._keyboard is None:
                self._requested_keyboard = True
                keyboard = self._keyboard =\
                    EventLoop.window.request_keyboard(
                        self._keyboard_released, self, input_type=self.input_type)
            ....
    

    希望对你有所帮助。

    【讨论】:

    • 我可以看到对 request_keyboard 的调用,感谢您指出这一点。我想找到它的原因是我可以看到它如何处理按键(即在 _on_keyboard_down 中),以便我可以看到它如何返回输入的字符。不幸的是,FocusBehaviour 似乎不是处理按键的地方。还是谢谢。
    • 你没有试过链接中的代码吗?我试了一下,它给了我密钥、键码和修饰符。如果你想要实际的字符(即用户按“a”和“shift”,所以字符是“A”),你可以绑定到键盘的 on_textinput() 方法。如果您真的非常想要扫描码,我认为您唯一的选择是编辑键盘源代码中的 _on_window_key_down() 以将扫描码也传递给 on_key_down()(糟糕,但有效)。或类似的东西。
    【解决方案2】:

    这是一个工作示例,如何处理修改后的字符。我知道这不是正确的解决方案,但它是有效的。如果您知道正确的方法,请在下面发布...

    代码:

    from kivy.app import App
    from kivy.uix.floatlayout import FloatLayout
    from kivy.properties import StringProperty
    from kivy.core.window import Window, Keyboard
    from kivy.logger import Logger
    
    class textInsert(FloatLayout):
        def __init__(self, **kwargs):
            super(textInsert, self).__init__(**kwargs)
            self.super = []
    
            text = StringProperty()
    
            ########################################
            keyboard = Window.request_keyboard(self._keyboard_released, self)
            keyboard.bind(on_key_down=self._keyboard_on_key_down, on_key_up=self._keyboard_released)
    
            ########################################
        #end def __init__
    
        def _keyboard_released(self, window, keycode):
            self.super = []
    
        def _keyboard_on_key_down(self, window, keycode, text, super):
            if 'lctrl' in self.super and keycode[1] == 's':
                Logger.info("Item saved, {}".format(self.super))
                self.super = []
                return False
            elif 'lctrl' not in self.super and keycode[1] in ["lctrl"]:
                self.super.append(keycode[1])
                return False
            else:
                Logger.info("key {} pressed.".format(keycode))
                return False
    
    
    class ROOT(App):
       def build(self):
          return textInsert()
    
    if __name__ == '__main__':
       ROOT().run()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      • 2011-03-21
      • 2021-06-30
      • 1970-01-01
      • 2013-02-13
      • 1970-01-01
      相关资源
      最近更新 更多