How to detect ESCape keypress in Python?

匿名 (未验证) 提交于 2019-12-03 01:56:01

问题:

I am running a process in a command window (Windows 7, Python 3.1) where I would like the user to abort the process by pressing the ESCape key. However, pressing the ESCape key doesn't appear to do anything :-(, the loop never breaks. I have also tried running the script from within my IDE (Wing), but again, the loop cannot be interrupted.

The following is a stripped-down version of my proof-of-concept test...

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! 

If anyone could tell me where I might be going wrong I would be most grateful.

回答1:

Python 3 strings are unicode and, therefore, must be encoded to bytes for comparison. Try this test:

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

Or this test:

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

Or this test:

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


回答2:

You should really strip down more, like this one below:

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

So here is the problem: msvcrt.getch() returns bytes, chr(27) returns string. In Python 3 they are two distinct types, so the "==" part will never work, and the if statement will always be evaluated as False.

The solution should be obvious to you.

More about strings vs bytes, from the book Dive into Python 3.

The interactive console is very useful for debugging, try use it more :)



回答3:

You don't need encode, decode, chr, ord, ....

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

or if you'd like to see "27" in the code somewhere:

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


回答4:

Python 2/3 compatible code:

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) 

Code parts are taken from pager module with more stuff inside.



回答5:

Have you tried using a different key to test if it's not just that key?

Did you also try the examples at (http://effbot.org/librarybook/msvcrt.htm) to see if they worked?



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!