tags:

views:

1366

answers:

6

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...
+5  A: 

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"

Mark Harrison
A: 

@Mark Harrison

That works...sorta. Got anything that will work in Windows?

Works great in Linux though. I'll keep it around for future refrence.

Grant
+2  A: 

On Windows:

import msvcrt
answer=msvcrt.getch()
Mark Harrison
+1  A: 

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.

Grant
A: 

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.

contagious
A: 

Mark, I suggest you edit the original question to make it clear that this is for Windows - since you rated the Windows-specific answer as the right answer.

Thomas Vander Stichele