在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的线程得到返回值?