本文介绍 Python 程序在 Windows 系统中监测键盘输入的两种方法:keyboard 和 pynput 工具包。


keyboard


keyboard 是一个第三方库,pip install 即可安装使用,官网链接如下:
keyboard, PyPI

本文以空格键暂停程序运行以获取键盘输入为例,展示 keyboard 的调用方法。

具体有两种方式实现。一种是 keyboard.hook 方法,相当于在进程中埋了一个“钩子”,在按下对应按键时触发一个函数,具体代码如下:

from datetime import datetime
import time

import keyboard

print()
dts = datetime.now()
flag = False


def abc(x):
    global flag
    a = keyboard.KeyboardEvent(event_type='down', scan_code=57, name='space')

    # # get key code and name
    # print("current key code:  {}".format(x.scan_code))
    # print("current key name:  {}".format(x.name))

    if x.event_type == a.event_type and x.scan_code == a.scan_code:
        print("You pressed {}.".format(a.name))
        flag = True


keyboard.hook(abc)
num_iter = 20

for i in range(num_iter):
    print(i)
    time.sleep(0.2) 
    if flag:
        print("Paused, please input something:")
        ipt = input()
        print("You input {}".format(ipt))
        flag = False

dte = datetime.now()
tm = round((dte - dts).seconds + (dte - dts).microseconds / (10 ** 6), 3)
print("total running time:  {} s".format(tm), '\n')

其中,keyboard.KeyboardEvent 中的 scan_code 和 name 参数即为按键的名称和代码,如果事先未知,可以在 abc 函数中 print 出来,参见注释掉的部分。这里列出几个常用按键的代码和名称:

namescan code
space57
enter28
ctrl29
shift42
right shift54
alt56
right alt56
backspace14
tab15
caps lock58
left windows91
esc1
up72
down80
left75
right77
`41
/53
\43
12
23
34
45
56
67
78
89
910
011

上述代码的运行效果如下:
hook

另一种方法是通过 keyboard.on_press 实现,代码如下:

import time

import keyboard


flag = False


def key_press(key):
    global flag
    if key.name == 'space':
        flag = True


keyboard.on_press(key_press)

num_iter = 20
for i in range(num_iter):
    print(i)
    time.sleep(0.2)
    if flag:
        print("Paused, please input something:")
        ipt = input()
        print("You input {}".format(ipt))
        flag = False

pynput


与 keyboard 相似,pynput 也是一个第三方库,pip install 即可安装使用,官网链接如下:
pynput, PyPI

除键盘监测外,pynput 还可以监测鼠标,本文暂不讨论该功能。

同样是以空格键暂停程序运行以获取键盘输入的场景,调用 pynput 时通过 pynput.keyboard.Listener 实现,具体代码如下:

import time

from pynput import keyboard


flag = False


def on_press(key):
    global flag

    if not flag:
        print("key {} is pressed".format(key))

    if key == keyboard.Key.space:
        flag = True


def on_release(key):
    pass


# ...or, in a non-blocking fashion:
listener = keyboard.Listener(
    on_press=on_press,
    on_release=on_release)
listener.start()

num_iter = 20
for i in range(num_iter):
    print(i)
    time.sleep(0.1)
    if flag:
        print("Paused, please input something:")
        ipt = input()
        print("You input {}".format(ipt))
        flag = False

局限性


如题所述,本文所介绍的两种方法都适用于 Windows 系统环境,但在远程控制 Linux 服务器时,这两种方法都会遇到问题,笔者暂未能解决,只好通过额外开启一个线程放置 input 函数来实现。

具体地,对于 pynput 工具包,官网给出了 platform limitation 的解释:
pynput, platform limitations

pynput, platform limitations, Linux

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐