# qPyMenu
A simple terminal menu system with ANSI formatting, logging, and threaded actions.
## Reference Documentation
[https://qpymenu.readthedocs.io/]
[https://pypi.org/project/qpymenu/0.6.0/]
```
pip install qpymenu
```
## Features
- Define Menus in JSON (new)
- Nested menus and menu items
- ANSI color and formatting support
- Logs actions and displays them on the right side
- Supports threaded execution of menu item actions
- Prompts for arguments if `""` is passed as args
## Usage
```python
from qpymenu import pyMenu, pyMenuItem
def test_function():
print("Hello from test_function!")
menu = pyMenu("Example Menu")
menu.additem(pyMenuItem("Test Item", test_function))
menu.execute()
```
## 📘 Module: `qpymenu.qpymenu`
### Class: `pyMenu`
```python
pyMenu(name: str = "Main Menu")
```
A terminal-based menu system that supports nested menus, ANSI formatting, logging, and threaded execution of actions.
#### Attributes
- **name** (`str`): The name shown at the top of the menu.
- **items** (`list`): Menu items.
- **current_index** (`int`): Current selection index for navigation.
#### Methods
##### `additem(item: pyMenuItem)`
Adds a `pyMenuItem` to the current menu.
- **Parameters**:
- `item` (`pyMenuItem`) – The menu item to be added.
- **Raises**:
- `TypeError` – If the provided item is not an instance of `pyMenuItem`.
---
##### `addsubmenu(submenu: pyMenu)`
Adds a submenu (`pyMenu`) to the current menu.
The submenu becomes a child of this menu, enabling nested navigation.
- **Parameters**:
- `submenu` (`pyMenu`) – The submenu instance to add.
---
##### `execute()`
Starts the interactive menu loop.
This method continuously displays the current menu, waits for user input, and navigates or executes based on the selection.
Input of `0` returns to the parent menu or exits if at the root level.
Logs each action and handles invalid input gracefully.
---
## Defining Menus using JSON
example menus.json file
```json
{
"name": "Main Menu",
"items": [
{
"type": "item",
"name": "Say Hello",
"action": "qpymenu.test_function",
"args": "",
"wait": true,
"threaded": false
},
{
"type": "submenu",
"name": "Utilities",
"items": [
{
"type": "item",
"name": "Show Time",
"action": "qpymenu.test_function"
}
]
}
]
}
```
##### `@staticmethod from_json(data: dict) -> pyMenu`
Creates a `pyMenu` instance (including nested submenus) from a JSON-like dictionary.
- **Parameters**:
- `data` (`dict`) – A dictionary representing the menu structure.
Expected keys: `name`, `items`, where each item has `type` (`item` or `submenu`).
- **Returns**:
- A fully constructed `pyMenu` object with items and nested submenus.
- **Raises**:
- `ValueError` – If the input structure is invalid.
---
##### `setformat(title_format: str = '\x1b[94m\x1b[1m', item_format: str = '\x1b[92m')`
Sets the ANSI color format for displaying the menu title and items.
- **Parameters**:
- `title_format` (`str`) – ANSI escape string for formatting the menu title.
- `item_format` (`str`) – ANSI escape string for formatting the menu items.
---
### Class: `pyMenuItem`
```python
pyMenuItem(name: str, action: callable = None, wait=True, args=None, threaded=False)
```
Represents a single menu item that can execute a callable action.
#### Attributes
- **name** (`str`): Display name of the item in the menu.
- **action** (`callable`, optional): The function to execute when selected.
- **wait** (`bool`): If `True`, waits for keypress after execution.
- **args** (`any`): Arguments to pass to the action (`None`, `tuple`, or `""` to prompt).
- **threaded** (`bool`): If `True`, runs the action in a new thread.
---
Raw data
{
"_id": null,
"home_page": null,
"name": "qpymenu",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "cli, menu, terminal, ansi, threading, interactive, pymenu",
"author": "David J. Cartwright",
"author_email": "\"David J. Cartwright\" <davidcartwright@hotmail.com>",
"download_url": "https://files.pythonhosted.org/packages/8d/ae/717c27f5206c48287274c630ec62466081d60f3b63a67e262adb148ff290/qpymenu-0.6.2.tar.gz",
"platform": null,
"description": "# qPyMenu\r\n\r\nA simple terminal menu system with ANSI formatting, logging, and threaded actions.\r\n\r\n\r\n## Reference Documentation\r\n[https://qpymenu.readthedocs.io/]\r\n\r\n[https://pypi.org/project/qpymenu/0.6.0/]\r\n\r\n```\r\npip install qpymenu\r\n```\r\n\r\n## Features\r\n\r\n- Define Menus in JSON (new)\r\n- Nested menus and menu items\r\n- ANSI color and formatting support\r\n- Logs actions and displays them on the right side\r\n- Supports threaded execution of menu item actions\r\n- Prompts for arguments if `\"\"` is passed as args\r\n\r\n## Usage\r\n\r\n```python\r\nfrom qpymenu import pyMenu, pyMenuItem\r\n\r\ndef test_function():\r\n print(\"Hello from test_function!\")\r\n\r\nmenu = pyMenu(\"Example Menu\")\r\nmenu.additem(pyMenuItem(\"Test Item\", test_function))\r\nmenu.execute()\r\n```\r\n\r\n\r\n\r\n## \ud83d\udcd8 Module: `qpymenu.qpymenu`\r\n\r\n### Class: `pyMenu`\r\n\r\n```python\r\npyMenu(name: str = \"Main Menu\")\r\n```\r\n\r\nA terminal-based menu system that supports nested menus, ANSI formatting, logging, and threaded execution of actions.\r\n\r\n#### Attributes\r\n\r\n- **name** (`str`): The name shown at the top of the menu. \r\n- **items** (`list`): Menu items. \r\n- **current_index** (`int`): Current selection index for navigation. \r\n\r\n#### Methods\r\n\r\n##### `additem(item: pyMenuItem)`\r\n\r\nAdds a `pyMenuItem` to the current menu.\r\n\r\n- **Parameters**: \r\n - `item` (`pyMenuItem`) \u2013 The menu item to be added. \r\n- **Raises**: \r\n - `TypeError` \u2013 If the provided item is not an instance of `pyMenuItem`.\r\n\r\n---\r\n\r\n##### `addsubmenu(submenu: pyMenu)`\r\n\r\nAdds a submenu (`pyMenu`) to the current menu. \r\nThe submenu becomes a child of this menu, enabling nested navigation.\r\n\r\n- **Parameters**: \r\n - `submenu` (`pyMenu`) \u2013 The submenu instance to add.\r\n\r\n---\r\n\r\n##### `execute()`\r\n\r\nStarts the interactive menu loop. \r\nThis method continuously displays the current menu, waits for user input, and navigates or executes based on the selection. \r\nInput of `0` returns to the parent menu or exits if at the root level. \r\nLogs each action and handles invalid input gracefully.\r\n\r\n---\r\n## Defining Menus using JSON\r\nexample menus.json file\r\n```json\r\n{\r\n \"name\": \"Main Menu\",\r\n \"items\": [\r\n {\r\n \"type\": \"item\",\r\n \"name\": \"Say Hello\",\r\n \"action\": \"qpymenu.test_function\",\r\n \"args\": \"\",\r\n \"wait\": true,\r\n \"threaded\": false\r\n },\r\n {\r\n \"type\": \"submenu\",\r\n \"name\": \"Utilities\",\r\n \"items\": [\r\n {\r\n \"type\": \"item\",\r\n \"name\": \"Show Time\",\r\n \"action\": \"qpymenu.test_function\"\r\n }\r\n ]\r\n }\r\n ]\r\n}\r\n```\r\n##### `@staticmethod from_json(data: dict) -> pyMenu`\r\n\r\nCreates a `pyMenu` instance (including nested submenus) from a JSON-like dictionary.\r\n\r\n- **Parameters**: \r\n - `data` (`dict`) \u2013 A dictionary representing the menu structure. \r\n Expected keys: `name`, `items`, where each item has `type` (`item` or `submenu`). \r\n- **Returns**: \r\n - A fully constructed `pyMenu` object with items and nested submenus. \r\n- **Raises**: \r\n - `ValueError` \u2013 If the input structure is invalid.\r\n\r\n---\r\n\r\n##### `setformat(title_format: str = '\\x1b[94m\\x1b[1m', item_format: str = '\\x1b[92m')`\r\n\r\nSets the ANSI color format for displaying the menu title and items.\r\n\r\n- **Parameters**: \r\n - `title_format` (`str`) \u2013 ANSI escape string for formatting the menu title. \r\n - `item_format` (`str`) \u2013 ANSI escape string for formatting the menu items.\r\n\r\n---\r\n\r\n### Class: `pyMenuItem`\r\n\r\n```python\r\npyMenuItem(name: str, action: callable = None, wait=True, args=None, threaded=False)\r\n```\r\n\r\nRepresents a single menu item that can execute a callable action.\r\n\r\n#### Attributes\r\n\r\n- **name** (`str`): Display name of the item in the menu. \r\n- **action** (`callable`, optional): The function to execute when selected. \r\n- **wait** (`bool`): If `True`, waits for keypress after execution. \r\n- **args** (`any`): Arguments to pass to the action (`None`, `tuple`, or `\"\"` to prompt). \r\n- **threaded** (`bool`): If `True`, runs the action in a new thread. \r\n\r\n---\r\n\r\n\r\n\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A terminal-based ANSI-formatted menu system with nested menus, threading, logging, and user prompts.",
"version": "0.6.2",
"project_urls": {
"Documentation": "https://qpymenu.readthedocs.io/en/latest/index.html",
"Homepage": "https://github.com/cartwrightdj/qpymenu",
"Issues": "https://github.com/cartwrightdj/qpymenu/issues"
},
"split_keywords": [
"cli",
" menu",
" terminal",
" ansi",
" threading",
" interactive",
" pymenu"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "ce452be3d5fea9d5a3a485919e99a3da9b04c5d7e03f386b763cd94f3cef2bbb",
"md5": "411cc85a91fe418b553fbf38322bf8f0",
"sha256": "c5050ca8de2d846d1bd1010810d00a078f6fdba67f2157204e92a4803eb54a85"
},
"downloads": -1,
"filename": "qpymenu-0.6.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "411cc85a91fe418b553fbf38322bf8f0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 8271,
"upload_time": "2025-07-27T00:30:36",
"upload_time_iso_8601": "2025-07-27T00:30:36.835365Z",
"url": "https://files.pythonhosted.org/packages/ce/45/2be3d5fea9d5a3a485919e99a3da9b04c5d7e03f386b763cd94f3cef2bbb/qpymenu-0.6.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8dae717c27f5206c48287274c630ec62466081d60f3b63a67e262adb148ff290",
"md5": "8f8630327a584d26e5fb42a7ea2587bd",
"sha256": "53925fee48c9c0145d7ee2e9846a3c493cc15814f5624a1a2fa8fd4db846a55d"
},
"downloads": -1,
"filename": "qpymenu-0.6.2.tar.gz",
"has_sig": false,
"md5_digest": "8f8630327a584d26e5fb42a7ea2587bd",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 8492,
"upload_time": "2025-07-27T00:30:38",
"upload_time_iso_8601": "2025-07-27T00:30:38.141615Z",
"url": "https://files.pythonhosted.org/packages/8d/ae/717c27f5206c48287274c630ec62466081d60f3b63a67e262adb148ff290/qpymenu-0.6.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-27 00:30:38",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "cartwrightdj",
"github_project": "qpymenu",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "qpymenu"
}