I've been trying to program a "press any key to continue" function, simply because raw_input feels noobish, but so far I haven't been having much luck.

I did a search and the opinions are nearly unanimous that getch() is the way to go, but...things haven't gone that well. Here's an example of what happens:

from msvcrt import getch
while 1:
   keyPressed = getch()
   print keyPressed
   if keyPressed == "x":
      break

The output of running this seemingly harmless program? An infinite loop, even after pressing "x". What's more, getch() seems to pick up the "enter" keystroke to execute this, long after I've lifted the key.

What this looks like to me --and I could be wrong-- is that keystrokes are stored in a stack or list of some sort, and the "Enter" keystroke is on the top of that. It seems that getch() reads the top entry, but *does not remove it*, causing that keystroke to be read for eternity.

I checked both the Python docs and the module docs for info on msvcrt to try to find a way to clear the "enter" keystroke and move on to the next one, but I found utterly nothing. At all.

Anyone know how it's done?

Dani AI

Generated

Two things are worth calling out from the thread: the environment (IDLE / GUI front-ends vs a real terminal) and the Python version/type semantics. ’s command-window test shows the environment issue — many console-level APIs don’t work the same inside IDLE/Tkinter. Separately, in Python 3 msvcrt.getch() returns a bytes object (for example b'x'), so comparing it to the text string "x" always fails and will look like an endless loop even when the key was pressed.

A small, practical cross-platform wrapper that returns a normal str (so equality checks like == 'x' behave) looks like this:

def getkey():
    try:
        import msvcrt
        return msvcrt.getwch()     # wide-char on Windows — returns str
    except ImportError:
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old = termios.tcgetattr(fd)
        try:
            tty.setraw(fd)
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old)
        return ch

Quick troubleshooting checklist: run the script from a real terminal (cmd.exe / PowerShell / a Unix terminal), inspect the raw return value with repr() and type() to see whether it’s bytes or str, and either decode bytes or use getwch() (or compare to a bytes literal like b'x') depending on the API in use. Note that special keys (arrow/function keys) are often delivered as multi-byte sequences or prefixes on Windows (a prefix code followed by a second code), so handle those if needed.

’s termios approach is the right direction for Unix systems, and ’s point about using line-based input (raw_input / input) stands if a full "press Enter" flow is acceptable. For simple, portable “press any key” behavior without per-platform fiddling, consider a small third-party helper (for example, packages that provide a single readchar/readkey function).

Recommended Answers

All 4 Replies

Are you running it in something like IDLE because if so getch wont work. Try using the python command window.

yeah i just checked the code in the command window and it works a-okay! :)

Using raw_input() makes more sense and it is portable across the different OS and editor output windows.

getch in Python is not easy. One implementation found on the web uses termios

import termios, sys, os                                                         
TERMIOS = termios                                                               
def getkey():                                                                   
        fd = sys.stdin.fileno()                                                 
        old = termios.tcgetattr(fd)                                             
        new = termios.tcgetattr(fd)                                             
        new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO                       
        new[6][TERMIOS.VMIN] = 1                                                
        new[6][TERMIOS.VTIME] = 0                                               
        termios.tcsetattr(fd, TERMIOS.TCSANOW, new)                             
        c = None                                                                
        try:                                                                    
                c = os.read(fd, 1)                                              
        finally:                                                                
                termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)                   
        return c                                                                
                                                                                
if __name__ == '__main__':                                                      
        print 'type something'                                                  
        s = ''                                                                  
        while 1:                                                                
                c = getkey()                                                    
                if c == 'q':                                                    
                        break                                                   
                print 'got ("q" = end)', c                                      
                s = s + c                                                       
                                                                                
        print s

Are there any ways to do something of that sort which are not Unix-only?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.