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


Translate

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...

Toutes les réponses
  • Translate

    On Windows:

    import msvcrt
    answer=msvcrt.getch()
    

  • Translate

    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"
    
    

  • Translate

    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.


  • Translate

    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.