pythonpynput

Is there a way to make pynput.keyboard count every press (short and long) just once with possibility holding multiple keys at once?


I tried to make simple key counter in python but i found a problem. When i held down a key for a while, it started fast couting cause i held down the key.

from pynput.keyboard import Listener
n = 0
def on_press(key):
    global n
    n += 1
def on_release(key):
    pass
with Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

So i made a lock, when im holding a key down, it can't count.

from pynput.keyboard import Listener
pressed = False
n = 0
def on_press(key):
    global n, pressed
    if pressed == False:
        n += 1
        pressed = True
def on_release(key):
    global pressed
    pressed = False
with Listener(on_press=on_press, on_release=on_release) as listener:
        listener.join()

But now when i start typing or playing games, it doesn't count every press, cause im sometimes holding 2 keys at the same time so 1 key isn't counted.

I tried locking after 0.5 seconds key was held down, so it counted every press when i was typing but there was still problem when i held down multiple keys for longer than 0.5 seconds (when i held down multiple keys for longer than 0.5 seconds, it counted only 1).

Is there a way to make it count every press (no matter if its long) just once with possibility holding multiple keys at once?


Solution

  • Your problem can be solved by keeping track which buttons are currently pressed in an array.

    from pynput.keyboard import Key, Listener
    
    keys_currently_pressed = []
    n = 0
    
    def on_press(key):
        global n
        if key not in keys_currently_pressed:
            keys_currently_pressed.append(key)
            n += 1
            print(key, 'pressed')
    
    def on_release(key):
        global n
        if key in keys_currently_pressed:
            keys_currently_pressed.remove(key)
        print(key, 'released')
        if key == Key.esc:
            print("You pressed", n, "keys")
            return False
    
    with Listener(on_press=on_press, on_release=on_release) as listener:
            listener.join()