2011-02-28 151 views
4

我運行在命令窗口(Windows 7,Python的3.1)的方法,其中,我想用戶通過按下退出鍵中止該過程。然而,按下ESCape鍵似乎沒有做任何事情:-(,循環不會中斷,我也嘗試從我的IDE(Wing)中運行腳本,但同樣,循環不能中斷。如何檢測Python中的ESCape按鍵?

以下是證明了概念我的測試的精簡版...

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

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 

或者這個測試:

+0

謝謝 - 所有3個解決方案都可以工作,所以現在我需要決定哪一個最適合我的編程風格;-)問候。 – 2011-02-28 20:25:20

1

你試過使用不同的密鑰進行測試,如果它不只是鑰匙?

迪你也嘗試在(http://effbot.org/librarybook/msvcrt.htm)的例子,看看他們的工作?

+0

嗨Corey,嘗試了建議的例子,並開始獲得「b'\ x1b'」輸出,這要感謝其他海報,我現在知道的是字節串版本,它必須轉換爲unicode。問候。 – 2011-02-28 20:29:35

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關於字符串VS字節,從書中深入Python 3

交互式控制檯對調試非常有用的,儘量使用更:)

+0

感謝您的回覆 - 爲我解釋它。問候 – 2011-02-28 20:14:29

3

你不需要編碼,解碼, CHR,ORD ....

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

,或者如果你想看到 「27」 在某處代碼:

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

在ASCII值上,我更喜歡第二個例子。謝謝。 – 2011-02-28 20:54:27

2

2/3的Python代碼兼容:

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模塊採取內部更多的東西。