在python中检测按键?

时间:2014-06-06 01:26:55

标签: python python-2.7 keypress detect

我正在python中制作秒表类型程序,我想知道如何检测是否按下某个键(例如p表示暂停,s表示停止),我不希望它像raw_input那样在继续执行之前等待用户的输入。任何人都知道如何在while循环中执行此操作?

另外,我想制作这个跨平台,但如果不可能,那么我的主要开发目标是linux

14 个答案:

答案 0 :(得分:32)

Python有一个keyboard模块,具有许多功能。安装它,也许使用此命令:

pip3 install keyboard

然后在代码中使用它:

import keyboard  # using module keyboard
while True:  # making a loop
    try:  # used try so that if user pressed other than the given key error will not be shown
        if keyboard.is_pressed('q'):  # if key 'q' is pressed 
            print('You Pressed A Key!')
            break  # finishing the loop
        else:
            pass
    except:
        break  # if user pressed a key other than the given key the loop will break

答案 1 :(得分:15)

OP提到raw_input - 这意味着他想要cli解决方案。 Linux:curses就是你想要的(windows PDCurses)。 Curses是cli软件的图形化API,您可以实现的不仅仅是检测关键事件。

此代码将检测按键,直到按下新行。

import curses
import os

def main(win):
    win.nodelay(True)
    key=""
    win.clear()                
    win.addstr("Detected key:")
    while 1:          
        try:                 
           key = win.getkey()         
           win.clear()                
           win.addstr("Detected key:")
           win.addstr(str(key)) 
           if key == os.linesep:
              break           
        except Exception as e:
           # No input   
           pass         

curses.wrapper(main)

答案 2 :(得分:11)

使用 keyboard 模块可以完成更多操作。

以下是一些方法:


方法1:

使用功能 read_key()

import keyboard

while True:
    if keyboard.read_key() == "p":
        print("You pressed p")
        break

按下 p 键将中断循环。


方法2:

使用功能 wait

import keyboard

keyboard.wait("p")
print("You pressed p")

它将等待您按下 p 并在按下时继续执行代码。


方法3:

使用功能 on_press_key

import keyboard

keyboard.on_press_key("p", lambda _:print("You pressed p"))

它需要一个回调函数。我使用_是因为键盘功能将键盘事件返回到该功能。

一旦执行,按下键将运行该功能。您可以通过运行以下行来停止所有挂钩:

keyboard.unhook_all()

方法4:

该方法已经被 user8167727 回答,但是我不同意他们编写的代码。它将使用功能 is_pressed ,但使用另一种方式:

import keyboard

while True:
    if keyboard.is_pressed("p"):
        print("You pressed p")
        break

按下 p 会中断循环。


注释:

  • keyboard将读取整个操作系统的按键。
  • keyboard要求在Linux上具有root权限

答案 3 :(得分:8)

对于 Windows ,您可以使用msvcrt,如下所示:

   import msvcrt
   while True:
       if msvcrt.kbhit():
           key = msvcrt.getch()
           print(key)   # just to show the result

答案 4 :(得分:8)

对于那些正在窗户上努力寻找可行答案的人,这里是我的: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()

上面的功能将打印您所按的任何键,并在释放'esc'键时开始执行操作。键盘文档为here,以了解更多用法。

答案 5 :(得分:6)

使用PyGame创建一个窗口,然后就可以获得关键事件。

对于字母p

import pygame, sys
import pygame.locals

pygame.init()
BLACK = (0,0,0)
WIDTH = 1280
HEIGHT = 1024
windowSurface = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)

windowSurface.fill(BLACK)

while True:
    for event in pygame.event.get():
        if event.key == pygame.K_p:
             #Do what you want to here
             pass
        if event.type == pygame.locals.QUIT:
             pygame.quit()
             sys.exit()

答案 6 :(得分:2)

使用此代码查找按下了哪个键

from pynput import keyboard

def on_press(key):
    try:
        print('alphanumeric key {0} pressed'.format(
            key.char))
    except AttributeError:
        print('special key {0} pressed'.format(
            key))

def on_release(key):
    print('{0} released'.format(
        key))
    if key == keyboard.Key.esc:
        # Stop listener
        return False

# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()

答案 7 :(得分:2)

您没有提到这是否是一个 GUI 程序,但大多数 GUI 程序包都包含一种捕获和处理键盘输入的方法。例如,使用 tkinter(在 Py3 中),您可以绑定到某个事件,然后在函数中处理它。例如:

import tkinter as tk

def key_handler(event=None):
    if event and event.keysym in ('s', 'p'):
        'do something'

r = tk.Tk()
t = tk.Text()
t.pack()
r.bind('<Key>', key_handler)
r.mainloop()

根据上述内容,当您在 Text 小部件中键入内容时,key_handler 例程会为您按下的每个(或几乎每个)键调用。

答案 8 :(得分:2)

neoDev 对问题本身的评论可能很容易被忽略,但它链接到此处任何答案中未提及的解决方案。

无需使用此解决方案导入 keyboard

this other question 复制的解决方案,所有功劳都归功于 @neoDev。

<块引用>

这在 macOS Sierra 和 Python 2.7.10 和 3.6.3 上对我有用

import sys,tty,os,termios
def getkey():
    old_settings = termios.tcgetattr(sys.stdin)
    tty.setcbreak(sys.stdin.fileno())
    try:
        while True:
            b = os.read(sys.stdin.fileno(), 3).decode()
            if len(b) == 3:
                k = ord(b[2])
            else:
                k = ord(b)
            key_mapping = {
                127: 'backspace',
                10: 'return',
                32: 'space',
                9: 'tab',
                27: 'esc',
                65: 'up',
                66: 'down',
                67: 'right',
                68: 'left'
            }
            return key_mapping.get(k, chr(k))
    finally:
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
try:
    while True:
        k = getkey()
        if k == 'esc':
            quit()
        else:
            print(k)
except (KeyboardInterrupt, SystemExit):
    os.system('stty sane')
    print('stopping.')

答案 9 :(得分:1)

我建议你使用PyGame并添加一个事件句柄。

http://www.pygame.org/docs/ref/event.html

答案 10 :(得分:1)

所以我根据这篇文章(使用msvcr库和Python 3.7)制作了这款游戏。.

以下是游戏的“主要功能”,即检测按下的键:

# Requiered libraries - - - -
import msvcrt
# - - - - - - - - - - - - - -


def _secret_key(self):
    # Get the key pressed by the user and check if he/she wins.

    bk = chr(10) + "-"*25 + chr(10)

    while True:

        print(bk + "Press any key(s)" + bk)
        #asks the user to type any key(s)

        kp = str(msvcrt.getch()).replace("b'", "").replace("'", "")
        # Store key's value.

        if r'\xe0' in kp:
            kp += str(msvcrt.getch()).replace("b'", "").replace("'", "")
            # Refactor the variable in case of multi press.

        if kp == r'\xe0\x8a':
            # If user pressed the secret key, the game ends.
            # \x8a is CTRL+F12, that's the secret key.

            print(bk + "CONGRATULATIONS YOU PRESSED THE SECRET KEYS!\a" + bk)
            print("Press any key to exit the game")
            msvcrt.getch()
            break
        else:
            print("    You pressed:'", kp + "', that's not the secret key(s)\n")
            if self.select_continue() == "n":
                if self.secondary_options():
                    self._main_menu()
                break

如果您想要完整的porgram源代码,则可以在此处查看或下载它:

The Secret Key Game (GitHub)

(注意:秘密按键为:CTRL + F12)

希望您可以作为一个例子,为那些来此信息的人提供帮助。

问候!

答案 11 :(得分:0)

key = cv2.waitKey(1)

这是来自openCV软件包。 它无需等待即可检测到按键。

答案 12 :(得分:0)

使用 keyboard 包,尤其是在 linux 上不是一个恰当的解决方案,因为该包需要 root 权限才能运行。我们可以使用 getkey package 轻松实现这一点。这类似于 C 语言中的 getchar 函数。

安装:

pip install getkey

并使用它:

from getkey import getkey
while True: #Breaks when key is pressed
    key = getkey()
    print(key) #Optionally prints out the key.
    break

我们可以将其添加到函数中以返回按下的键。

def Ginput(str):
    """
    Now, this function is like the native input() function. It can accept a prompt string, print it out, and when one key is pressed, it will return the key to the caller.
    """
    print(str, end='')
    while True:
        key = getkey()
        print(key)
        return key

像这样使用:

inp = Ginput("\n Press any key to continue: ")
print("You pressed " + inp)

答案 13 :(得分:-1)

您可以使用键盘模块。只需打开终端并输入:

<块引用>

pip 安装键盘

这是代码:

import keyboard
while true:
    try:
        if keyboard.is_pressed('s'):
            print("stop")
        elif keyboard.is_pressed('p'):
            print("pause")
    except:
        pass