'detect key press in python, where each iteration can take more than a couple of seconds?

Edit: The below answer to use keyboard.on_press(callback, suppress=False) works fine in ubuntu without any issues. But in Redhat/Amazon linux, it fails to work.

I have used the code snippet from this thread

import keyboard  # using module keyboard
while True:  # making a loop
    try:  # used try so that if user pressed other than the given key error will not be shown
        if keyboard.is_pressed('q'):  # if key 'q' is pressed 
            print('You Pressed A Key!')
            break  # finishing the loop
    except:
        break  # if user pressed a key other than the given key the loop will break

But the above code requires the each iteration to be executed in nano-seconds. It fails in the below case:

import keyboard  # using module keyboard
import time
while True:  # making a loop
    try:  # used try so that if user pressed other than the given key error will not be shown
        print("sleeping")
        time.sleep(5)
        print("slept")
        if keyboard.is_pressed('q'):  # if key 'q' is pressed 
            print('You Pressed A Key!')
            break  # finishing the loop
    except:
        print("#######")
        break  # if user pressed a key other than the given key the loop will break


Solution 1:[1]

You can make use of event handlers in keyboard module to achieve the desired result.

One such handler is keyboard.on_press(callback, suppress=False): Which invokes a callback for every key_down event. You can refer more at keyboard docs

Here is the code you can try:

import keyboard  # using module keyboard
import time

stop = False
def onkeypress(event):
    global stop
    if event.name == 'q':
        stop = True

# ---------> hook event handler
keyboard.on_press(onkeypress)
# --------->

while True:  # making a loop
    try:  # used try so that if user pressed other than the given key error will not be shown
        print("sleeping")
        time.sleep(5)
        print("slept")
        if stop:  # if key 'q' is pressed 
            print('You Pressed A Key!')
            break  # finishing the loop
    except:
        print("#######")
        break  # if user pressed a key other than the given key the loop will break

Solution 2:[2]

for people that might need this in the future, you can use keyboard.wait() which will basically wait untill the key gets pressed

keyboard.wait("o")
print("you pressed the letter o")

Do keep in mind that it blocks code execution after it. if you want to run code if the key is not being pressed i'd suggest doing

if keyboard.is_pressed("0"): 
    #do stuff
else: 
    #do other stuff

Solution 3:[3]

Edit: never mind, the other answer uses pretty much the same approach

This is what i could come up with, using the same "keyboard" module, see in-code comments below

import keyboard, time
from queue import Queue 

# keyboard keypress callback
def on_keypress(e): 
    keys_queue.put(e.name)

# tell keyboard module to tell us about keypresses via callback
# this callback happens on a separate thread
keys_queue = Queue() 
keyboard.on_press(on_keypress)

try:
    # run the main loop until some key is in the queue
    while keys_queue.empty():  
        print("sleeping")
        time.sleep(5)
        print("slept")
    # check if its the right key
    if keys_queue.get()!='q':
        raise Exception("terminated by bad key")
    # still here? good, this means we've been stoped by the right key
    print("terminated by correct key")
except:
    # well, you can 
    print("#######")
finally:
    # stop receiving the callback at this point
    keyboard.unhook_all()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shubham Sharma
Solution 2 supermitch
Solution 3 Boris Lipschitz