8

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
Naren Babu R
  • 453
  • 2
  • 9
  • 33
  • 1
    Your program will detect nothing during the sleep call. What are you trying to do? – James Mar 02 '20 at 13:51
  • @James The above program is just a illustration. Problem is, key press is not detected if each iteration in while loop is taking more than a couple of seconds. – Naren Babu R Mar 02 '20 at 13:56
  • Check this examples https://stackoverflow.com/a/31736883/5274713 – frost-nzcr4 Mar 02 '20 at 14:02
  • Did you try with another library? like evemu and python-evdev, keyboard had been inconsistent (for me at least) – RMPR Mar 13 '20 at 11:10

4 Answers4

7

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
Shubham Sharma
  • 68,127
  • 6
  • 24
  • 53
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
supermitch
  • 2,062
  • 4
  • 22
  • 28
Mana
  • 41
  • 1
  • Is there a way to use `keyboard.wait()` to wait for ANY key event, either a key up or key down? – will-hedges May 20 '22 at 22:14
  • 1
    @will-hedges There is!, With `trigger_on_release=` if true, the callback is invoked on key release instead of key press. In the case below it triggers when the key is released `keyboard.wait("o", trigger_on_release=True) print("you released the letter o")` – Mana Jan 05 '23 at 14:47
-1

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()
Boris Lipschitz
  • 1,514
  • 8
  • 12
-3

You could use a thread

import threading

class KeyboardEvent(threading.Thread):
    def run(self):
        if keyboard.is_pressed('q'):  # if key 'q' is pressed 
            print('You Pressed A Key!')
            break  # finishing the loop

keyread = KeyboardEvent()
keyread.start()

This would run in parallel to anything in the main thread and be dedicated to listening for that key press essentially.

Tom
  • 42
  • 6
  • If I'm not mistaken, though, it would just check for the keypress once the thread was started, and then the thread would exit. Did you mean `while not keyboard.is_pressed` instead? – akasaka Mar 13 '20 at 07:28