Is it possible to get a single key press without having the user press enter? So, say if you were writing a game, say an RPG, to high WASD to move. Ie:

x = getkey()
if x = "w"
    # blah blah blah
if x = "a"
    # blah blah blah
if x = "s"
    # blah blah blah
if x = "d"
    # blah blah blah

I read about a getch() function, but I don't know if that's what I'm looking for.

You can use Tkinter running in the background:

# respond to a key without the need to press enter

import Tkinter as tk

def keypress(event):
    if event.keysym == 'Escape':
        root.destroy()
    x = event.char
    if x == "w":
        print "blaw blaw blaw"
    elif x == "a":
        print "blaha blaha blaha"
    elif x == "s":
        print "blash blash blash"
    elif x == "d":
        print "blad blad blad"
    else:
        print x


root = tk.Tk()
print "Press a key (Escape key to exit):"
root.bind_all('<Key>', keypress)
# don't show the tk window
root.withdraw()
root.mainloop()

You can use getch(), but it has limitations:

# print characters typed, no Enter needed
# works only with Windows since it imports msvcrt.dll
# also works only in the cmd window

from msvcrt import getch

while True:
    z = getch()
    # escape key to exit
    if ord(z) == 27:
        break
    print z

This is the only one that I know of, although I think there is something that uses ncurses as well. Also, you want double equals here if x == "w", and if you have a lot a compares, you can use a dictionary with the function name, or the print literal as the value.

import termios, sys, os
#import termios, 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 == '\n':     ## break on a Return/Enter keypress
                        break
                print 'got', c
                s = s + c

        print s

You can use Tkinter running in the background:

# respond to a key without the need to press enter

import Tkinter as tk

def keypress(event):
    if event.keysym == 'Escape':
        root.destroy()
    x = event.char
    if x == "w":
        print "blaw blaw blaw"
    elif x == "a":
        print "blaha blaha blaha"
    elif x == "s":
        print "blash blash blash"
    elif x == "d":
        print "blad blad blad"
    else:
        print x


root = tk.Tk()
print "Press a key (Escape key to exit):"
root.bind_all('<Key>', keypress)
# don't show the tk window
root.withdraw()
root.mainloop()

You can use getch(), but it has limitations:

# print characters typed, no Enter needed
# works only with Windows since it imports msvcrt.dll
# also works only in the cmd window

from msvcrt import getch

while True:
    z = getch()
    # escape key to exit
    if ord(z) == 27:
        break
    print z

The second one won't work, because I don't use Windows, but I'll try Tkinter. I was hoping for something built right into Python without importing libraries, but this works just as well.

The binding to the <Key>-Event works well - there is just on problem. If I type for example a lot of 'a's into notepad by just holding that key, there is one a typed and then a short break. After that the computer continues to type 'a's.

This effect also takes place in the <Key>-Event. Of course for navigation like the WASD-navigation in games, this is very annoying.

Is there anything I can do for not having this break?

This article has been dead for over six months. Start a new discussion instead.