Blursed Menu
blursedmenu is a framework to build menu-driven text user interfaces in
any terminal.
This is at the same time cursed, in that it is a weird way to structure a
program, and blessed, because it does not use the (n)curses library.
How To Use It In Your Project
The most common way to use blursedmenu would be to add it as a dependency
to your project.
Alternatively you might just copy the blursedmenu.py file into your
project. Note that the copyright notice and license information at the top
of the file still apply.
Example
A minimal example of a menu usage can be found in minimal.py (although
it's not that minimal because it implements a item_action). If you want
the minimal thing, but don't like classes, have a look at
minimal_no_class.py - it does the same thing as minimal.py.
There is also a more complex example of a file browser written using Menu in
demo.py.
Features
- no (n)curses, any terminal can show this
- optional readline support (for completion and history)
- for lazy typers: commands can be abbreviated to their shortest
non-ambiguous name (e.g.
hinstead ofhelp)
Structure and Usage
In general a Menu has Items and Commands.
Items are stored in Menu.items by calling Menu.build_items and can
be listed in an enumerated form, so the user can easily refer to the items
by number.
Commands are used to interact with the items and to control the program
itself. By default these commands are set up:
quit, implemented inQuitCommandto exit the menu,list, implemented inListCommandto list the items,help, implemented inHelpComandto show the help of other commands.
A menu is run by calling Menu.run() and it can return an exit code to
indicate success (it returns 0 by default).
To implement your own menu, you usually want to add an implementation to
Menu.build_items and add your own commands to your menu's
self.commands.
Items
Items are rebuilt every time with a call to build_items() just before
the user is being asked to provide input (see Best Practices below).
Individual menu items can be as simple as strings (see minimal.py) or
your own implementation of Item, in case you have more complex data
structures than a string.
A good example is SelectableItem, which allows the user to toggle the
selected state of an item.
Commands
Your custom commands should implement self.execute() and use
self.item() to resolve the user-provided item number and do stuff with
it.
The documentation string of your custom command is shown to the user by the
HelpCommand.
Item Action
If you only want the user to select an item and go on with it, you should
use assign a function to Menu.item_action. That function will receive the
selected menu item as the first argument.
Note that SelectableItems will never use the item_action (because these
toggle their 'selected' state instead), so you want to have the item action
also available as a command.
Various Other Parts
The prompt that is shown to the user is controlled via the Menu.prompt
variable. You could set the prompt based on the current context, menu, or
state.
There is a Menu.description that will be shown to the user when the menu
is started. You can use it to provide some information what the
user can do.
User Input
If you want to get input from the user, you could just use input, but
there's also Menu.ask that handles errors and, if readline support is
available, allows you to provide the default value and even tab-completion.
Sub-menus
To launch a submenu, create a command and in the execute() function
instantiate the new menu and run it.
It's usually a good idea for submenus to pass the originating menu as
parent into the constructor of Menu.
Have a look at submenu.py for an example.
Hooks
There are a few hooks that you can use:
on_startis executed immediately when the menu'srunis called,before_inputis executed every time just before the user is asked for input,after_executeis executed after a command has been run and the returned value from that command'sexecutecall is passed in as the first (and only) argument.on_exitis the last thing that's executed in the menu'srunfunction and the returned value fromon_exitis also returned fromrun.
Best Practices
The build_items() function is called from the default implementation of
Menu.before_input. That means it is run every time before the user is
prompted for input!
You may want to consider to not rebuild the items with this:
def build_items(self):
if len(self.items) > 0:
return
Now, if you want to rebuild the items (for example from a 'reload' command or otherwise when you know the items have changed), you simply clear the menu's items.
Here's an example command that does just that:
class ReloadCommand(blursedmenu.Command):
def execute(self, *_):
self.menu.items = []
Copyright and License
Copyright 2026 vonshednob, licensed under the EUPL
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.