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

Tags: python
By : Grant
Source: Stackoverflow.com
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...
By : Grant


Answers

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"



On Windows:

import msvcrt
answer=msvcrt.getch()


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.

By : Grant


This video can help you solving your question :)
By: admin