Search code examples
pythonkivyuser-inputkeyboard-shortcutskey-bindings

Kivy & Python: How to activate a function using a key press from user?


I'm very new to Kivy and Python. A few weeks in.

I'm trying create a counter that will take user input (via key stroke) to increment a value. I've tried various codes, but I cannot seem to get it right. Here is what I have at this moment. I'm having the most trouble on the on_key_down function. I press the 'p' key but nothing happens.

main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.properties import ObjectProperty
from kivy.core.window import Window

class MyLayout(GridLayout):
    def __init__(self, **kwargs):
        super(MyLayout, self).__init__(**kwargs)
        self.total_count = 0 # Initialize the total count

    def increment_total_count(self, instance):
        # Function to increment total count and update label
        self.total_count += 1
        self.ids.total_counter.text = str(self.total_count)

    def on_key_down(self, window, keycode, text, modifiers, is_repeat, *args):
        if isinstance(keycode, (list, tuple)) and len(keycode) > 1: #added because I kept getting an 'int' error when pressing 'p'
            if keycode[1] == 'p': # If you hit the key 'p'
                self.ids.increment_button.dispatch('on_release')

class Counter(App):
    def build(self):
        root = MyLayout()
        Window.bind(on_key_down = root.on_key_down)
        return root

if __name__ == "__main__":
    Counter().run()

.kv file

GridLayout:
    cols: 2

    Label:
        id: total_counter
        text: "0"

    Button:
        id: increment_button
        text: "Increment"
        on_release: root.increment_total_count(self) # Run increment_total_count from main.py

I got the button to work on mouse-click; but would like the user to be able to push a key 'p' to trigger the same function as the button.

Thank you in advance for helping!


Solution

  • Try replacing your on_key_down() method with:

    def on_key_down(self, window, keycode, text, modifiers, is_repeat, *args):
        if Keyboard.keycodes['p'] == keycode:
            self.ids.increment_button.dispatch('on_release')
    

    This requires an import of Keyboard:

    from kivy.core.window import Window, Keyboard