在Python中轮询键盘(检测按键)

我怎样才能从控制台python应用程序轮询键盘? 具体来说,我想在很多其他I / O活动(套接字select,串口访问等)中做类似的事情:

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的可移植性不会太差,尽pipe这不是必需的。

标准的方法是使用select模块。

但是,这在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 

好吧,因为我试图发表我的解决scheme的评论失败了,这就是我想说的。 我可以用下面的代码来完成我从本地Python(在Windows上,不在其他地方)

 import msvcrt def kbfunc(): x = msvcrt.kbhit() if x: ret = ord(msvcrt.getch()) else: ret = 0 return ret 

使用curses模块的解决scheme。 打印与每个按键相对应的数值:

 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) 

你可以看看pygame如何处理这个来窃取一些想法。

这些答案都不适合我。 这个包,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() 

来自评论:

 import msvcrt # built-in module def kbfunc(): return ord(msvcrt.getch()) if msvcrt.kbhit() else 0 

谢谢您的帮助。 我最终编写了一个名为PyKeyboardAccess.dll的C DLL,并访问crt conio函数,导出这个例程:

 #include <conio.h> int 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) 

如果结合time.sleep,threading.Thread和sys.stdin.read,您可以轻松地等待input的指定时间,然后继续,也应该跨平台兼容。

 t = threading.Thread(target=sys.stdin.read(1) args=(1,)) t.start() time.sleep(5) t.join() 

你也可以把它放到像这样的函数中

 def timed_getch(self, bytes=1, timeout=1): t = threading.Thread(target=sys.stdin.read, args=(bytes,)) t.start() time.sleep(timeout) t.join() del t 

虽然这不会返回任何东西,所以你应该使用多处理池模块,你可以在这里find: 如何从python的线程得到返回值?