Hotkeys in Kivy-desktop

Question:

I would like to add Hotkeys to my project.

For example: ctrl + S for saving

I found a small working example. But it tests only whether one key is pressed or not.
How could I check for multiple button pressed?

edit: the modifiers is an empty list. How can I use the modifiers?

Here is the code I tried:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.properties import StringProperty,ObjectProperty
from kivy.core.window import Window, Keyboard
from kivy.logger import Logger

class textInsert(FloatLayout):
    def __init__(self, **kwargs):
        super(textInsert, self).__init__(**kwargs)

        text = StringProperty()

      ########################################
        keyboard = Window.request_keyboard(self._keyboard_released, self)
        keyboard.bind(on_key_down=self._keyboard_on_key_down)
        ########################################

     #end def __init__

    def _keyboard_released(self):
        self.focus = False

    def _keyboard_on_key_down(self, window, keycode, text, modifiers):

        if keycode[1] in ["s","y","q","w"]:
           print("its in the list")
           return True
        else:
           print('returned false')
           return False


class ROOT(App):
   def build(self):
      return textInsert()

if __name__ == '__main__':
   ROOT().run()
Asked By: picibucor

||

Answers:

On my machine, the Control key is not stored in the modifiers list, but it has a specific keycode. In my case, printing the arguments of on_key_down when pressing Ctrl would yield something like:

(<kivy.core.window.window_sdl2.WindowSDL object at 0x7fc094802360>, 305, 224, u'u0131', [])

In my kivy version, there is one additional argument on on_key_down so you’ll have do adjust it accordingly to your version. Just for reference, the arguments for the “S” key are:

(<kivy.core.window.window_sdl2.WindowSDL object at 0x7fc094802360>, 115, 22, u's', [])

To bind multiple keys, simply use a conditional with multiple statements. In my case, I would do:

def _keyboard_on_key_down(self, window, keycode1, keycode2, text, modifiers):

   #Check if Control AND "S" are both pressed
   if keycode1 == 305 and keycode1 == 115:
      #do something
Answered By: ODiogoSilva

Here is a working example, of how to handle modified characters. I know it is not the proper solution, but it works. If you know the proper way, please post it below…

code:

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()
Answered By: picibucor

”’No need to go complex
here is the code for hotkeys”’

from kivy.app import App

from kivy.uix.widget import Widget
from kivy.core.window import Window

class KeyDown(App):
def build(self):
Window.bind(on_key_down=self.key_action)
return Widget()

if name == ‘main‘:
KeyDown().run()

Answered By: kavitha r
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.