【问题标题】:How to detect ESCape keypress in Python?如何在 Python 中检测 ESCape 按键?
【发布时间】:2022-02-07 19:52: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!

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

【问题讨论】:

    标签: python windows escaping keypress


    【解决方案1】:

    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
    

    【讨论】:

    • 谢谢 - 所有 3 个解决方案都有效,所以现在我需要决定哪一个最适合我的编程风格 ;-) 问候。
    【解决方案2】:

    你不需要encode、decode、chr、ord、....

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

    或者如果您想在代码中的某处看到“27”:

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

    【讨论】:

    • 在 ASCII 值上长大,我更喜欢第二个例子。谢谢。
    【解决方案3】:

    你真的应该减少更多,就像下面这个:

    >>> 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 关于字符串与字节,来自 Dive into Python 3 一书。

    交互式控制台对调试很有用,多用试试:)

    【讨论】:

      【解决方案4】:

      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 模块,里面有更多内容。

      【讨论】:

        【解决方案5】:

        您是否尝试过使用不同的密钥来测试它是否不仅仅是那个密钥?

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

        【讨论】:

        • 嗨,Corey,尝试了建议的示例并开始获得“b'\x1b'”输出,感谢这里的其他海报,我现在知道是字节串版本,它必须转换为 unicode。问候。
        猜你喜欢
        • 1970-01-01
        • 2013-08-17
        • 1970-01-01
        • 2021-12-27
        • 2010-09-22
        • 2018-01-17
        • 2014-03-25
        • 1970-01-01
        相关资源
        最近更新 更多