如何从控制台python应用程序轮询键盘?具体来说,我想在许多其他I/O活动(套接字选择,串行端口访问等)中做类似的事情:
while 1: # doing amazing pythonic embedded stuff # ... # periodically do a non-blocking check to see if # we are being told to do something else x = keyboard.read(1000, timeout = 0) if len(x): # ok, some key got pressed # do something
在Windows上执行此操作的正确pythonic方法是什么?此外,Linux的可移植性也不错,但并不是必需的.
标准方法是使用选择模块.
但是,这在Windows上不起作用.为此,您可以使用msvcrt模块的键盘轮询.
通常,这是通过多个线程完成的 - 每个设备被"监视"一个加上可能需要被设备中断的后台进程.
import sys import select def heardEnter(): i,o,e = select.select([sys.stdin],[],[],0.0001) for s in i: if s == sys.stdin: input = sys.stdin.readline() return True return False
使用curses模块的解决方案.打印与按下的每个键对应的数值:
import curses def main(stdscr): # do not wait for input when calling getch stdscr.nodelay(1) while True: # get keyboard input, returns -1 if none available c = stdscr.getch() if c != -1: # print numeric value stdscr.addstr(str(c) + ' ') stdscr.refresh() # return curser to start position stdscr.move(0, 0) if __name__ == '__main__': curses.wrapper(main)
好吧,既然我试图在评论中发布我的解决方案失败了,这就是我想说的.我可以使用以下代码完成我想要的原生Python(在Windows上,而不是其他任何地方):
import msvcrt def kbfunc(): x = msvcrt.kbhit() if x: ret = ord(msvcrt.getch()) else: ret = 0 return ret
这些答案都不适合我.这个包pynput完全符合我的需要.
https://pypi.python.org/pypi/pynput
from pynput.keyboard import Key, Listener def on_press(key): print('{0} pressed'.format( key)) def on_release(key): print('{0} release'.format( key)) if key == Key.esc: # Stop listener return False # Collect events until released with Listener( on_press=on_press, on_release=on_release) as listener: listener.join()
你可能会看看pygame如何处理这个以窃取一些想法.
来自评论:
import msvcrt # built-in module def kbfunc(): return ord(msvcrt.getch()) if msvcrt.kbhit() else 0
谢谢您的帮助.我最终编写了一个名为PyKeyboardAccess.dll的C DLL并访问了crt conio函数,导出了这个例程:
#includeint kb_inkey () { int rc; int key; key = _kbhit(); if (key == 0) { rc = 0; } else { rc = _getch(); } return rc; }
我使用ctypes模块(内置到python 2.5中)在python中访问它:
import ctypes import time # # first, load the DLL # try: kblib = ctypes.CDLL("PyKeyboardAccess.dll") except: raise ("Error Loading PyKeyboardAccess.dll") # # now, find our function # try: kbfunc = kblib.kb_inkey except: raise ("Could not find the kb_inkey function in the dll!") # # Ok, now let's demo the capability # while 1: x = kbfunc() if x != 0: print "Got key: %d" % x else: time.sleep(.01)