用Pynput监听特定的按键

时间:2019-07-30 00:46:10

标签: python pynput

我希望我的代码侦听用户输入,如果按下键c可以执行某些操作,如果按下键v可以执行其他操作。

我已经设法使用global来做到这一点,但是感觉就像是一个丑陋的骇客:

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()

有更好的方法吗? (也许是通过让侦听器停止并返回c中的值von_press()来实现的?如果是这样,我将找不到方法。)

还:由于wait_for_user_input()将被多次调用,所以最好不要重复启动和停止侦听器,而是先启动一次并停止一次吗?

1 个答案:

答案 0 :(得分:1)

您可以将函数直接放在on_press中,然后就不需要while循环。您可能只需要listener.join()即可等待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        

编辑:

如果您需要运行功能,而其他功能则需要,那么您可以继续使用global user_input,但可以编写一些不同的内容。

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 ?')

编辑:如果您使用Windows,则可以使用msvcrt.getch,它可以使代码更短,更好。

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()

对于Linux,应该使用类似的功能getch(),但代码要更长。

另请参阅模块getch,但我没有检查它。