如何在Python中检测ESC键按下?
我在一个命令窗口里运行一个程序(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