How do I make a menu that does not require the user to press [enter] to make a selection?

StackOverflow https://stackoverflow.com/questions/1829

  •  08-06-2019
  •  | 
  •  

Question

I've got a menu in Python. That part was easy. I'm using raw_input() to get the selection from the user.

The problem is that raw_input (and input) require the user to press Enter after they make a selection. Is there any way to make the program act immediately upon a keystroke? Here's what I've got so far:

import sys
print """Menu
1) Say Foo
2) Say Bar"""
answer = raw_input("Make a selection> ")

if "1" in answer: print "foo"
elif "2" in answer: print "bar"

It would be great to have something like

print menu
while lastKey = "":
    lastKey = check_for_recent_keystrokes()
if "1" in lastKey: #do stuff...
Was it helpful?

Solution

On Windows:

import msvcrt
answer=msvcrt.getch()

OTHER TIPS

On Linux:

  • set raw mode
  • select and read the keystroke
  • restore normal settings
import sys
import select
import termios
import tty

def getkey():
    old_settings = termios.tcgetattr(sys.stdin)
    tty.setraw(sys.stdin.fileno())
    select.select([sys.stdin], [], [], 0)
    answer = sys.stdin.read(1)
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
    return answer

print """Menu
1) Say Foo
2) Say Bar"""

answer=getkey()

if "1" in answer: print "foo"
elif "2" in answer: print "bar"

Wow, that took forever. Ok, here's what I've ended up with

#!C:\python25\python.exe
import msvcrt
print """Menu
1) Say Foo 
2) Say Bar"""
while 1:
    char = msvcrt.getch()
    if char == chr(27): #escape
        break
    if char == "1":
        print "foo"
        break
    if char == "2":
        print "Bar"
        break

It fails hard using IDLE, the python...thing...that comes with python. But once I tried it in DOS (er, CMD.exe), as a real program, then it ran fine.

No one try it in IDLE, unless you have Task Manager handy.

I've already forgotten how I lived with menus that arn't super-instant responsive.

The reason msvcrt fails in IDLE is because IDLE is not accessing the library that runs msvcrt. Whereas when you run the program natively in cmd.exe it works nicely. For the same reason that your program blows up on Mac and Linux terminals.

But I guess if you're going to be using this specifically for windows, more power to ya.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top