Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a menu in Python navigable with arrow keys

Tags:

python

menu

I'm making a text-based game with an option to select a class for their character. At present, the player enters their option, either typing in a number or the name of the class. It works well enough.

However, I would like to have the player navigate the menu with the arrow keys and select an option using the "enter" key. In order to make it clear which option they are about to select, I would also like to have the text of the selected option highlighted. If you've ever played an ASCII roguelike, you know what it looks like.

Here is the code that I currently have for classes:

def character():

    print "What is your class?"
    print "1. The sneaky thief."
    print "2. The smarty wizard."
    print "3. The proletariat."

    charclass = raw_input("> ")
        if charclass == "1" or "thief":
            charclass = thief
            print "You are a thief!"

        elif charclass == "2" or "wizard":
            charclass = wizard
            print "You are a wizard!"

        elif charclass == "3" or "prole":
            charclass = prole
            print "You are a prole!"

        else:
            print "I'm sorry, I didn't get that"

Thanks!

like image 957
Gaffsey Avatar asked Sep 14 '16 11:09

Gaffsey


1 Answers

As it was already mentioned in a comment, you may use curses. Here is a small working menu to achieve what you want

import curses

classes = ["The sneaky thief", "The smarty wizard", "The proletariat"]


def character(stdscr):
    attributes = {}
    curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
    attributes['normal'] = curses.color_pair(1)

    curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_WHITE)
    attributes['highlighted'] = curses.color_pair(2)

    c = 0  # last character read
    option = 0  # the current option that is marked
    while c != 10:  # Enter in ascii
        stdscr.erase()
        stdscr.addstr("What is your class?\n", curses.A_UNDERLINE)
        for i in range(len(classes)):
            if i == option:
                attr = attributes['highlighted']
            else:
                attr = attributes['normal']
            stdscr.addstr("{0}. ".format(i + 1))
            stdscr.addstr(classes[i] + '\n', attr)
        c = stdscr.getch()
        if c == curses.KEY_UP and option > 0:
            option -= 1
        elif c == curses.KEY_DOWN and option < len(classes) - 1:
            option += 1

    stdscr.addstr("You chose {0}".format(classes[option]))
    stdscr.getch()


curses.wrapper(character)

The last call to getch is just so you can see the result before the program terminates

like image 110
Jona Avatar answered Sep 29 '22 17:09

Jona