Skip to main content

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. h instead of help)

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 in QuitCommand to exit the menu,
  • list, implemented in ListCommand to list the items,
  • help, implemented in HelpComand to 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_start is executed immediately when the menu's run is called,
  • before_input is executed every time just before the user is asked for input,
  • after_execute is executed after a command has been run and the returned value from that command's execute call is passed in as the first (and only) argument.
  • on_exit is the last thing that's executed in the menu's run function and the returned value from on_exit is also returned from run.

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.

Source Distribution

blursedmenu-0.1.0.tar.gz (13.2 kB view details)

Uploaded Source

File details

Details for the file blursedmenu-0.1.0.tar.gz.

File metadata

  • Download URL: blursedmenu-0.1.0.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.5

File hashes

Hashes for blursedmenu-0.1.0.tar.gz
Algorithm Hash digest
SHA256 635022edb655fb19e4781fd1da3b9ba320d028e822752c3fc97fb2a1d5d8a1b4
MD5 6a595bec72f758ea5b99386d00994251
BLAKE2b-256 f6e76dcb4c4b180f4436e1c24cd9a8fbe94b9f729cb1c6da25ceb7bc60d52a14

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

1 file

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page