问题
I'd like my code to listen for user input, and do something if key c
is pressed, and something else if key v
is pressed.
I've managed to do it using global
, but it feels like an ugly hack :
from pynput import keyboard
def on_press(key):
try:
global user_input
if key.char == "c":
user_input = "c"
elif key.char == "v":
user_input == "v"
except AttributeError:
pass
def on_release(key):
if key == keyboard.Key.esc:
# Stop listener
return False
def wait_for_user_input():
global user_input
listener = keyboard.Listener(on_press=on_press, on_release=on_release)
listener.start()
user_input = 0
while user_input == 0:
time.sleep(0.5)
if user_input == "c":
# do something
listener.stop()
break
elif user_input == "v":
# do something else
listener.stop()
break
# other stuff
wait_for_user_input()
Is there a better way to do it ? (Maybe by having the listener stop & return the values c
or v
in on_press()
? If so, I couldn't find how to do it.)
Also : since wait_for_user_input()
will be called multiple times, would it be better to not start and stop the listener repetitively, and instead have it start once and stop once ?
回答1:
You can put functions directly in on_press
and then you don't need while
loop. You may need only listener.join()
which will wait for listener.stop()
from pynput import keyboard
def on_press(key):
try:
if key.char == "c":
# do something
return False # Stop listener
elif key.char == "v":
# do something else
return False # Stop listener
except AttributeError as ex:
print(ex)
def on_release(key):
if key == keyboard.Key.esc:
# Stop listener
return False
def wait_for_user_input():
listener = keyboard.Listener(on_press=on_press, on_release=on_release)
listener.start()
listener.join() # wait till listener will stop
# other stuff
EDIT:
If you need run functions which result you need in other functions then you may stay with global user_input
but you can write it little different.
from pynput import keyboard
def on_press(key):
global user_input
try:
if key.char in ("c", "v"):
user_input = key.char
return False # Stop listener
except AttributeError as ex:
print(ex)
def on_release(key):
if key == keyboard.Key.esc:
return False # Stop listener
def wait_for_user_input():
listener = keyboard.Listener(on_press=on_press, on_release=on_release)
listener.start()
listener.join() # wait till listener will stop
if user_input == "c":
# do something
elif user_input == "v":
# do something else
else:
print('You pressed ESC ?')
EDIT: If you use Windows then you could use msvcrt.getch
which gives shorter and nicer code.
from msvcrt import getch
def wait_for_user_input():
while True:
user_input = getch()
if user_input == "c":
print('selected: c')
break
elif user_input == "v":
print('selected: v')
break
elif user_input == escape:
print('You pressed ESC ?')
break
wait_for_user_input()
For Linux should be similar function getch()
but with longer code.
See also module getch but I didn't check it.
来源:https://stackoverflow.com/questions/57262917/listening-for-specific-keys-with-pynput