如何在Python中检测ESC键按下?

14 投票
6 回答
74412 浏览
提问于 2025-04-16 12:38

我在一个命令窗口里运行一个程序(Windows 7,Python 3.1),我希望用户能通过按 Esc 键来中止这个程序。但是,按了 Esc 键似乎没有任何反应,循环一直没有停止。我也试过在我的IDE(Wing)里运行这个脚本,但同样,循环也无法被打断。

下面是我测试的一个简化版本……

import msvcrt
import time

aborted = False

for time_remaining in range(10,0,-1):
    # First of all, check if ESCape was pressed
    if msvcrt.kbhit() and msvcrt.getch()==chr(27):
        aborted = True
        break

    print(str(time_remaining))       # so I can see loop is working
    time.sleep(1)                    # delay for 1 second
#endfor timing loop

if aborted:
    print("Program was aborted")
else:
    print("Program was not aborted")

time.sleep(5)  # to see result in command window before it disappears!

如果有人能告诉我哪里出错了,我会非常感激。

6 个回答

6

你应该把代码简化得更彻底,就像下面这个:

>>> import msvcrt
>>> ch = msvcrt.getch()
# Press esc
>>> ch
b'\x1b'
>>> chr(27)
'\x1b'
>>> ch == chr(27)
False

问题在于:msvcrt.getch() 返回的是 bytes 类型,而 chr(27) 返回的是 string 类型。在 Python 3 中,这两者是完全不同的类型,所以 "==" 这个比较永远不会成立,if 语句总是会被判断为 False

解决办法应该很明显了。

关于字符串和字节的更多信息,可以参考《Dive into Python 3》这本书。

交互式控制台对于调试非常有用,尽量多用它哦 :)

6

你不需要使用编码、解码、字符转换(chr)、字符的数字表示(ord)等等。

if msvcrt.kbhit() and msvcrt.getch() == b'\x1b':

或者如果你想在代码中看到“27”这个数字:

if msvcrt.kbhit() and msvcrt.getch()[0] == 27:
8

Python 3中的字符串是Unicode格式的,因此在进行比较时,必须先将它们转换成字节格式。你可以试试这个测试:

if msvcrt.kbhit() and msvcrt.getch() == chr(27).encode():
    aborted = True
    break

或者试试这个测试:

if msvcrt.kbhit() and msvcrt.getch().decode() == chr(27):
    aborted = True
    break

再或者试试这个测试:

if msvcrt.kbhit() and ord(msvcrt.getch()) == 27:
    aborted = True
    break

撰写回答