问题:在python中检测按键?
我正在用python开发一个秒表类型的程序,我想知道如何检测是否按下了一个键(例如p表示暂停,s表示停止),而我不希望它像raw_input这样等待用户输入,然后继续执行。有人知道如何在while循环中执行此操作吗?
另外,我想做这个跨平台的,但是如果那不可能,那么我的主要开发目标是linux
回答 0
Python有一个具有许多功能的键盘模块。安装它,也许使用以下命令:
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
    except:
        break  # if user pressed a key other than the given key the loop will break回答 1
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”键时启动操作。键盘文档在这里用于更多变化的用法。
马库斯·冯·布罗迪(Markus von Broady)强调了一个潜在的问题,即:这个答案并不需要您在当前窗口中激活此脚本,Windows的解决方案是:
from win32gui import GetWindowText, GetForegroundWindow
current_window = (GetWindowText(GetForegroundWindow()))
desired_window_name = "Stopwatch" #Whatever the name of your window should be
#Infinite loops are dangerous.
while True: #Don't rely on this line of code too much and make sure to adapt this to your project.
    if current_window == desired_window_name:
        with Listener(
            on_press=on_press,
            on_release=on_release) as listener:
            listener.join()回答 2
正如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)回答 3
使用keyboard模块可以做更多的事情。
以下是一些方法:
方法1:
使用功能read_key():
import keyboard
while True:
    if keyboard.read_key() == "p":
        print("You pressed p")
        breakp按下该键将打破循环。
方法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")
        breakp按下将打破循环。
笔记:
- keyboard将从整个操作系统读取按键。
- keyboard在Linux上需要root
回答 4
对于Windows,您可以这样使用msvcrt:
   import msvcrt
   while True:
       if msvcrt.kbhit():
           key = msvcrt.getch()
           print(key)   # just to show the result回答 5
使用此代码查找按下了哪个键
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()回答 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: # replace the 'p' to whatever key you wanted to be pressed
             pass #Do what you want to here
        if event.type == pygame.locals.QUIT:
             pygame.quit()
             sys.exit()回答 7
所以我根据这篇文章(使用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的完整源代码,则可以在这里查看或下载它:
(注意:秘密按键为:Ctrl+ F12)
我希望您可以作为一个例子,并为那些来此信息的人提供帮助。
回答 8
我建议您使用PyGame并添加一个事件句柄。
回答 9
key = cv2.waitKey(1)这是来自openCV软件包。它无需等待即可检测到按键。

