当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在python中轮询键盘(检测按键)》经验,为你挑选了7个好方法。

如何从控制台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的可移植性也不错,但并不是必需的.



1> S.Lott..:

标准方法是使用选择模块.

但是,这在Windows上不起作用.为此,您可以使用msvcrt模块的键盘轮询.

通常,这是通过多个线程完成的 - 每个设备被"监视"一个加上可能需要被设备中断的后台进程.



2> 小智..:
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



3> 小智..:

使用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)



4> K. Brafford..:

好吧,既然我试图在评论中发布我的解决方案失败了,这就是我想说的.我可以使用以下代码完成我想要的原生Python(在Windows上,而不是其他任何地方):

import msvcrt 

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



5> wroscoe..:

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


这对我有用,除了按下的键在按下后立即回显到屏幕上,并且无法禁用它。https://github.com/moses-palmer/pynput/issues/47另外,这些字符被缓冲,并且在程序退出时也出现在命令行上。这似乎是Linux实现的局限性,但它可以工作在Windows上很好。

6> Rizwan Kassi..:

你可能会看看pygame如何处理这个以窃取一些想法.


PyGame事件处理仅适用于GUI,不适用于OP要求的控制台。

7> K. Brafford..:

来自评论:

import msvcrt # built-in module

def kbfunc():
    return ord(msvcrt.getch()) if msvcrt.kbhit() else 0

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

#include 

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)

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有