如何检测键盘按键?

203 投票
17 回答
953516 浏览
提问于 2025-04-18 08:48

我正在用Python制作一个计时器程序,想知道怎么检测按键是否被按下(比如按p暂停,按s停止),而不是像raw_input那样,等用户输入后再继续执行。

有没有人知道怎么在一个循环里做到这一点?

我希望这个程序可以在不同的平台上运行,但如果不行的话,我主要是想在Linux上开发。

17 个回答

30

Windows系统上,你可以这样使用msvcrt

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

正如提问者提到的raw_input,这意味着他想要一个命令行界面的解决方案。在Linux系统中,你可以使用curses库(在Windows上用PDCurses)。Curses是一个用于命令行软件的图形化接口,你可以做的不仅仅是检测按键事件。

这段代码会一直检测按键,直到按下换行键为止。

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)
94

keyboard模块可以做很多事情。你可以通过命令pip install 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键时,这个循环就会停止。


方法 #5:

你也可以使用keyboard.record。这个方法会记录你按下和释放的所有键,直到你按下escape键或者你在until参数中定义的键,并返回一个包含keyboard.KeyboardEvent元素的列表。

import keyboard

keyboard.record(until="p")
print("You pressed p")

注意事项:

  • keyboard模块会读取整个操作系统的按键。
  • keyboard在Linux上需要管理员权限。
104

对于那些在Windows系统上苦苦寻找有效答案的人,这里有我的推荐:pynput

这里是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'键时开始一个动作。关于键盘的更多用法,可以查看这里的文档。

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()
142

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
    except:
        break  # if user pressed a key other than the given key the loop will break

撰写回答