如何在Python中检测ESCape keypress?

时间:2011-02-28 00:56:32

标签: python windows escaping keypress

我正在命令窗口(Windows 7,Python 3.1)中运行一个进程,我希望用户通过按ESCape键来中止该进程。但是,按ESCape键似乎没有做任何事情:-(,循环永远不会中断。我也尝试从我的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!

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

5 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:5)

您不需要编码,解码,chr,ord,....

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

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

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

答案 2 :(得分:4)

你真的应该删除更多,如下所示:

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

所以问题在于:msvcrt.getch()返回byteschr(27)返回string。在Python 3中,它们是两种不同的类型,因此“==”部分永远不会起作用,if语句将始终被评估为False

解决方案应该是显而易见的。

关于字符串与字节的

More,从“潜入Python 3”一书开始。

交互式控制台对于调试非常有用,请尝试使用它:)

答案 3 :(得分:3)

Python 2/3兼容代码:

import time, sys

ESC = '\x1b'
PY3K = sys.version_info >= (3,)
if PY3K:
    from msvcrt import kbhit, getwch as _getch
else:
    from msvcrt import kbhit, getch as _getch
while not kbhit() or _getch() != ESC:
    print(time.asctime())
    time.sleep(1)

代码部分取自pager模块,其中包含更多内容。

答案 4 :(得分:1)

您是否尝试使用其他密钥来测试它是否只是那个密钥?

您是否也尝试过(http://effbot.org/librarybook/msvcrt.htm)的示例,看看它们是否有效?