是否有一种在Python中无需使用类似于pygame
这样臃肿的模块来实现键盘监听的方法?
例如,当我按下a键时,它应该会在控制台上打印以下内容:
按下了a键!
它还应该监听方向键、空格键和Shift键。
是否有一种在Python中无需使用类似于pygame
这样臃肿的模块来实现键盘监听的方法?
例如,当我按下a键时,它应该会在控制台上打印以下内容:
按下了a键!
它还应该监听方向键、空格键和Shift键。
我正在寻找一种不需要窗口焦点的简单解决方案。Jayk的答案,pynput
,对我来说非常完美。这是我如何使用它的示例。
from pynput import keyboard
def on_press(key):
if key == keyboard.Key.esc:
return False # stop listener
try:
k = key.char # single-char keys
except:
k = key.name # other keys
if k in ['1', '2', 'left', 'right']: # keys of interest
# self.keys.append(k) # store it in global-like variable
print('Key pressed: ' + k)
return False # stop listener; remove this if want more keys
listener = keyboard.Listener(on_press=on_press)
listener.start() # start to listen on a separate thread
listener.join() # remove if main thread is polling self.keys
while True: pass
。 - Sylvester Kruin很不幸,要做到这一点并不容易。如果您想要创建某种文本用户界面,您可能需要研究 curses
。如果您想像在终端中那样显示内容,但希望输入不同,则必须使用 termios
来处理,不幸的是,这在Python中似乎缺乏文档说明。不过,这两个选项都不是那么简单的。此外,它们不能在Windows下工作;如果您需要在Windows下使用它们,则必须使用 PDCurses 代替 curses
或者使用 pywin32 而不是 termios
。
我成功地实现了这个功能。它输出您键入的十六进制表示。正如我在您的问题评论中所说,箭头键比较棘手;我认为您会同意这一点。
#!/usr/bin/env python
import sys
import termios
import contextlib
@contextlib.contextmanager
def raw_mode(file):
old_attrs = termios.tcgetattr(file.fileno())
new_attrs = old_attrs[:]
new_attrs[3] = new_attrs[3] & ~(termios.ECHO | termios.ICANON)
try:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, new_attrs)
yield
finally:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, old_attrs)
def main():
print 'exit with ^C or ^D'
with raw_mode(sys.stdin):
try:
while True:
ch = sys.stdin.read(1)
if not ch or ch == chr(4):
break
print '%02x' % ord(ch),
except (KeyboardInterrupt, EOFError):
pass
if __name__ == '__main__':
main()
pynput
库而不是这个库的答案。 - kynan在 Python 中有一种处理按键监听的方式,可以通过 pynput 实现。
命令行:
$ pip install pynput
Python 代码:
from pynput import keyboard
# your code here
以下是在Windows上的操作步骤:
"""
Display series of numbers in infinite loop
Listen to key "s" to stop
Only works on Windows because listening to keys
is platform dependent
"""
# msvcrt is a windows specific native module
import msvcrt
import time
# asks whether a key has been acquired
def kbfunc():
#this is boolean for whether the keyboard has bene hit
x = msvcrt.kbhit()
if x:
#getch acquires the character encoded in binary ASCII
ret = msvcrt.getch()
else:
ret = False
return ret
#begin the counter
number = 1
#infinite loop
while True:
#acquire the keyboard hit if exists
x = kbfunc()
#if we got a keyboard hit
if x != False and x.decode() == 's':
#we got the key!
#because x is a binary, we need to decode to string
#use the decode() which is part of the binary object
#by default, decodes via utf8
#concatenation auto adds a space in between
print ("STOPPING, KEY:", x.decode())
#break loop
break
else:
#prints the number
print (number)
#increment, there's no ++ in python
number += 1
#wait half a second
time.sleep(0.5)
while True:
换行 x = kbfunc()
换行 if x != False:
换行 print("keypress:", x.decode())
。这对我来说很好用。不知道你是否知道如何让终端在失去焦点时仍然能够监听按键事件。 - Musixauce3000sudo pip install keyboard
使用这个小型Python库完全控制你的键盘。钩子全局事件,注册热键,模拟按键等等。
在所有键盘上进行全局事件钩子(无论焦点在哪里,都可以捕捉键)。 监听和发送键盘事件。 支持Windows和Linux(需要sudo),具有实验性的OS X支持(感谢@glitchassassin!)。 纯Python,无需编译C模块。 零依赖项。安装和部署简单,只需复制文件即可。 Python 2和3。 支持复杂的热键(例如Ctrl+Shift+M,Ctrl+Space),并且超时可控。 包括高级API(例如记录和播放,添加缩写)。 将键映射为您布局中实际存在的键,并具有完全的国际化支持(例如Ctrl+ç)。 事件自动在单独的线程中捕获,不会阻塞主程序。 经过测试和文档化。 不影响重音死键(我在看你,pyHook)。 鼠标支持可通过项目mouse获取(pip install mouse)。
来自README.md:
import keyboard
keyboard.press_and_release('shift+s, space')
keyboard.write('The quick brown fox jumps over the lazy dog.')
# Press PAGE UP then PAGE DOWN to type "foobar".
keyboard.add_hotkey('page up, page down', lambda: keyboard.write('foobar'))
# Blocks until you press esc.
keyboard.wait('esc')
# Record events until 'esc' is pressed.
recorded = keyboard.record(until='esc')
# Then replay back at three times the speed.
keyboard.play(recorded, speed_factor=3)
# Type @@ then press space to replace with abbreviation.
keyboard.add_abbreviation('@@', 'my.long.email@example.com')
# Block forever.
keyboard.wait()
虽然我喜欢使用键盘模块来捕获键盘事件,但我不喜欢它的record()
函数,因为它返回一个数组,类似于[KeyboardEvent("A"), KeyboardEvent("~")]
,我觉得这有点难以阅读。因此,为了记录键盘事件,我喜欢同时使用键盘模块和线程模块,像这样:
import keyboard
import string
from threading import *
# I can't find a complete list of keyboard keys, so this will have to do:
keys = list(string.ascii_lowercase)
"""
Optional code(extra keys):
keys.append("space_bar")
keys.append("backspace")
keys.append("shift")
keys.append("esc")
"""
def listen(key):
while True:
keyboard.wait(key)
print("[+] Pressed",key)
threads = [Thread(target=listen, kwargs={"key":key}) for key in keys]
for thread in threads:
thread.start()
from pynput import keyboard
def on_activate_a():
print('A pressed')
def on_activate_b():
print('B pressed')
def on_activate_c():
print('C pressed')
def quit():
print('QUIT')
h.stop()
with keyboard.GlobalHotKeys({
'a': on_activate_a,
'b': on_activate_b,
'c': on_activate_c,
'<ctrl>+c': quit}) as h:
h.join()