pythonpython-3.xhotkeyspynput

How to detect hot-keys in Python


I need a way to detect hot-key presses in pure python code.

I tried using the snippet of code that I wrote:

import pynput

def on_press_keyboard(key):
    try:
        print('hold ' + str(key.char))
    except AttributeError:
        print('hold ' + str(key))

def on_release_keyboard(key):
    try:
        print('release ' + str(key.char))
    except AttributeError:
        print('release ' + str(key))


keyboard_listener = pynput.keyboard.Listener(on_press=on_press_keyboard, on_release=on_release_keyboard)
keyboard_listener.start()
keyboard_listener.join()

but in the on_press_keyboard function it prints weird things when I press multiple keys at the same time for example here is the output of when I press Ctrl+a:

hold Key.ctrl_l
hold ☺
release ☺
release Key.ctrl_l

it prints a smiley face??

How can I get it to properly print these keys individually for example make it output like this:

hold Key.ctrl_l
hold a
release a
release Key.ctrl_l

Hot-Key detected: Ctrl+a

Solution

  • I did a lot of digging, and this is the best method I could find to detect hotkeys. Pynput is pretty much out of the window, because it does those weird characters. Keyboard isn't much more promising, but you can detect if hotkeys were pressed in keyboard. Here's an example of what I came up with:

    import keyboard
    
    hotkeys = []
    letters = 'abcdefghijklmnopqrstuvwxyz'
    
    def on_press(hotkey):
        print(f"You pressed a hotkey: {hotkey}")
    
    for i in range(2):
        for letter in range(26):
            if i == 0:
                hotkeys.append(("ctrl", letters[letter]))
            else:
                hotkeys.append(("alt", letters[letter]))
    
    while True:
        for hotkey in hotkeys:
            if keyboard.is_pressed(f"{hotkey[0]}+{hotkey[1]}"):
                on_press(f"{hotkey[0]}+{hotkey[1]}")
    

    This is the best code I could come up with. First, we make a list called hotkeys to store all possible pairings of hotkeys (I only did ctrl and alt). Next, I paired it up with all letters of the alphabet. You could add more combinations of possible hotkeys if you wanted. This code works perfectly, but it is very inefficient as it requires the code to check through lots of combinations of hotkeys, and is limited to the number of hotkeys that you decide to put in the list.