Advertisement
FocusedWolf

Python: Simple Console Menu

Feb 15th, 2023 (edited)
1,265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.79 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. # Online post: https://pastebin.com/zv9EXdgH
  4.  
  5. # This is a port of my C# Menu to Python: https://pastebin.com/9NmGvV4y
  6.  
  7. # SOURCE: https://docs.python.org/2/library/curses.html
  8. # SOURCE: https://docs.python.org/3/howto/curses.html
  9.  
  10. # For Windows: pip install windows-curses
  11. import curses
  12. window = curses.initscr() # Initialize the library. Returns a WindowObject which represents the whole screen.
  13. window.keypad(True) # Escape sequences generated by some keys (keypad, function keys) will be interpreted by curses.
  14. curses.cbreak() # Keys are read one by one. Also safer than curses.raw() because you can interrupt a running script with SIGINT (Ctrl + C).
  15. curses.noecho() # Prevent getch() keys from being visible when pressed. Echoing of input characters is turned off.
  16.  
  17. # Initialize colors.
  18. curses.start_color() # Must be called if you want to use colors.
  19. curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
  20. curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
  21. curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK)
  22. curses.init_pair(4, curses.COLOR_GREEN, curses.COLOR_BLACK)
  23. curses.init_pair(5, curses.COLOR_YELLOW, curses.COLOR_BLACK)
  24. curses.init_pair(6, curses.COLOR_BLUE, curses.COLOR_BLACK)
  25. curses.init_pair(7, curses.COLOR_MAGENTA, curses.COLOR_BLACK)
  26. curses.init_pair(8, curses.COLOR_CYAN, curses.COLOR_BLACK)
  27. black = curses.color_pair(1)
  28. white = curses.color_pair(2)
  29. red = curses.color_pair(3)
  30. green = curses.color_pair(4)
  31. yellow = curses.color_pair(5)
  32. blue = curses.color_pair(6)
  33. magenta = curses.color_pair(7)
  34. cyan = curses.color_pair(8)
  35.  
  36. # -----
  37.  
  38. def draw_menu(menuItems, selectedIndex):
  39.     #  window.erase()
  40.     window.clear()
  41.  
  42.     # Print a vertical menu.
  43.     for i in range(len(menuItems)):
  44.         window.addstr(' ')
  45.         window.addstr(menuItems[i], black if i == selectedIndex else white)
  46.         window.addstr('\n\n')
  47.  
  48.     # Print a dividing line.
  49.     window.addstr(('-' * 80) + '\n')
  50.  
  51.     # Print a horizontal menu.
  52.     for i in range(len(menuItems)):
  53.         window.addstr(' ')
  54.         window.addstr(menuItems[i], black if i == selectedIndex else white)
  55.  
  56.     window.addstr('\n')
  57.  
  58. # -----
  59.  
  60. def process_input(menuItems, selectedIndex):
  61.     userInput = window.getch()
  62.  
  63.     if userInput == curses.KEY_LEFT or userInput == curses.KEY_UP:
  64.         # Loop around backwards.
  65.         selectedIndex = (selectedIndex - 1 + len(menuItems)) % len(menuItems)
  66.  
  67.     elif userInput == curses.KEY_RIGHT or userInput == curses.KEY_DOWN:
  68.         # Loop around forwards.
  69.         selectedIndex = (selectedIndex + 1) % len(menuItems)
  70.  
  71.     # If curses.nonl() is called, Enter key = \r else \n.
  72.     elif userInput == curses.KEY_ENTER or chr(userInput) in '\r\n':
  73.         # If the last option, exit, is selected.
  74.         if selectedIndex == len(menuItems) - 1:
  75.             wait_for_any_keypress()
  76.             curses.endwin() # De-initialize the library, and return terminal to normal status.    <-- Works without this on Windows, however in Linux you can't type in the terminal after exiting without this :P
  77.             exit(0)
  78.  
  79.         window.addstr('\n Selected index: {}\n'.format(selectedIndex))
  80.         wait_for_any_keypress()
  81.  
  82.     else:
  83.         window.addstr("\n The pressed key '{}' {} is not associated with a menu function.\n".format(chr(userInput), userInput))
  84.         wait_for_any_keypress()
  85.  
  86.     return selectedIndex
  87.  
  88. # -----
  89.  
  90. def wait_for_any_keypress():
  91.     window.addstr('\n Press any key to continue . . . ')
  92.     window.getch()
  93.  
  94. # -----
  95.  
  96. def main():
  97.     selectedIndex = 0
  98.     while True:
  99.         draw_menu(MENU_ITEMS, selectedIndex)
  100.         selectedIndex = process_input(MENU_ITEMS, selectedIndex)
  101.  
  102. MENU_ITEMS = [
  103.     ' Option 1 ',
  104.     ' Option 2 ',
  105.     ' Option 3 ',
  106.     ' Exit ',
  107. ]
  108.  
  109. if __name__ == '__main__':
  110.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement