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()
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
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()
”’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()
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()
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
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()
”’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()