A multi-application marking menu and UI framework for Maya, 3ds Max, and Blender.
Project description
Tentacle
A Qt-based marking menu (pie menu) for DCC apps, with a full toolkit for Maya.
Tentacle gives you a fast, gesture-driven launcher for tools and commands inside Autodesk Maya, 3ds Max, and Blender. Press a hotkey, flick the mouse toward a wedge, release — and the tool runs. Submenus open along the gesture path, so common multi-step actions become single muscle-memory motions.
It ships with 60+ pre-built Maya tool panels (modeling, UVs, materials, rigging, animation, rendering, …) covering most day-to-day work. The Blender and 3ds Max entry points are scaffolded but do not yet ship a slot library.
Table of contents
- Why Tentacle
- Install
- Launch
- How it works
- Project layout
- Adding your own menu
- Customization
- Platform support
- Development
- Further reading
Why Tentacle
- Gesture-first. Activate from anywhere, never break flow to hunt through Maya's shelf or menu bar.
- Convention over configuration. A
.uifile plus a Python class with matching method names (b005→def b005(...)) is all it takes to add a tool. - Composable. UIs and slots are decoupled — swap the front-end without touching command logic.
- Battery-included for Maya. Ships with curated panels for nearly every DCC discipline — see
tentacle/slots/maya/.
Install
Tentacle is published to PyPI as tentacletk. Install into your DCC's bundled Python (Maya example):
"C:/Program Files/Autodesk/Maya2025/bin/mayapy.exe" -m pip install tentacletk
Or use the mayapy package manager (give your Maya version, press 1, type tentacletk).
Requirements: Python 3.9+, Qt via qtpy (PySide2 or PySide6), and the upstream toolkit packages pythontk, uitk, and mayatk (installed automatically as dependencies).
Launch
Add to your Maya userSetup.py:
from maya.utils import executeDeferred
def start_tentacle():
from tentacle import TclMaya
TclMaya(key_show="F12") # Hold F12 to summon the marking menu
executeDeferred(start_tentacle)
key_show accepts either bare keys ("F12", "Space") or fully-qualified Qt names ("Key_F12").
To launch standalone for development:
python -m tentacle.tcl_maya
How it works
flowchart TD
A["TclMaya<br/>tentacle/tcl_maya.py"] --> B["MarkingMenu<br/>uitk"]
B --> C["Switchboard<br/>uitk — loads .ui files,<br/>binds widgets to slots"]
C --> D["UI files<br/>tentacle/ui/*.ui"]
C --> E["Slot classes<br/>tentacle/slots/maya/*.py"]
B --> F["Overlay<br/>uitk — gesture path drawing"]
A --> G["MayaUiHandler<br/>mayatk — Maya host integration"]
TclMaya is a thin Maya-flavored subclass of uitk.MarkingMenu. All the heavy lifting — input state machine, gesture overlay, dynamic UI loading, slot binding — lives in uitk. Tentacle's job is to provide:
- The Maya host wiring (parent window, UI handler).
- Default key/mouse-button → start-menu bindings.
- The library of
.uifiles and matching slot classes.
Default key bindings
With the default key_show="F12":
| Gesture | Opens |
|---|---|
F12 |
hud#startmenu |
F12 + Left Mouse |
cameras#startmenu |
F12 + Middle Mouse |
editors#startmenu |
F12 + Right Mouse |
main#startmenu |
F12 + Left + Right (chord) |
maya#startmenu |
Inside any menu, Ctrl+Shift+R repeats the last command. Override the bindings or shortcut via Customization.
Marking-menu interaction
- Press and hold the activation key — a radial menu appears centered on the cursor.
- Drag toward a wedge. A trailing path is drawn so you can see your gesture history.
- If the wedge has a submenu, it opens along the path — keep dragging.
- Release over a leaf wedge to invoke its slot.
Tap-and-release without dragging shows the menu pinned, so you can click items directly.
UI ↔ slot wiring
Tentacle relies on naming conventions, enforced by tests in test/test_ui_integrity.py and test/test_slot_integrity.py:
| Convention | Example |
|---|---|
| UI file name → menu identity | materials.ui, main#startmenu.ui |
Widget objectName → slot method |
b005 → def b005(self) |
| Optional setup hook | def b005_init(self, widget) |
| Header section initializer | def header_init(self, widget) |
Info button (i###) accessibleName → submenu UI name |
i000.accessibleName = "polygons" |
Widget prefixes carry semantic meaning, recognized by Switchboard:
| Prefix | Widget kind |
|---|---|
b### |
QPushButton |
tb### |
Tool button (with option box) |
cmb### |
QComboBox / dropdown |
list### |
Expandable list |
chk### |
Checkbox |
lbl### |
Label (clickable) |
i### |
Info / submenu router |
Project layout
tentacle/
├── tcl_maya.py # Maya entry point — TclMaya class
├── tcl_max.py # 3ds Max wrapper (TclMax)
├── tcl_blender.py # Blender wrapper (TclBlender)
├── slots/
│ ├── _slots.py # Base Slots class — repeat-last-command shortcut
│ └── maya/
│ ├── _slots_maya.py # SlotsMaya base for all Maya slot classes
│ ├── materials.py # MaterialsSlots — example slot module
│ ├── animation.py
│ └── ... (~55 modules covering all DCC disciplines)
└── ui/
├── *.ui # Top-level menu definitions
├── *#startmenu.ui # Wedges for the radial start menus
├── *#submenu.ui # Submenu panels reached via i### routers
└── maya_menus/ # Maya-specific submenus
Each slot module pairs with one or more .ui files of the same basename. The Switchboard resolves the pair at load time.
Adding your own menu
Minimal recipe to add a new tool panel:
-
Create the UI in Qt Designer and save as
tentacle/ui/my_tools.ui. Add buttons and set theirobjectNameto follow the prefix convention (b000,b001, …). -
Create the slot class at
tentacle/slots/maya/my_tools.py:from tentacle.slots.maya._slots_maya import SlotsMaya class MyToolsSlots(SlotsMaya): def __init__(self, switchboard): super().__init__(switchboard) self.ui = self.sb.loaded_ui.my_tools def b000_init(self, widget): # optional setup hook widget.setToolTip("Run the thing.") def b000(self): print("Hello from my_tools b000")
-
Wire it into a start menu by adding an info-button (
i###) to e.g.main#startmenu.uiwhoseaccessibleNameequals"my_tools". Or bind it directly to a key via thebindingsargument toTclMaya.
The package's tests will fail if a UI/slot pair is mismatched, so structural mistakes are caught early.
Customization
TclMaya accepts overrides for activation key, bindings, slot directory, and log level:
from tentacle import TclMaya
TclMaya(
key_show="F11", # change activation key
slot_source="my_studio/slots", # use a custom slot library
log_level="DEBUG", # uitk MarkingMenu log verbosity
bindings={ # fully replace the default bindings
"Key_F11": "main#startmenu",
"Key_F11|RightButton": "cameras#startmenu",
},
)
User-facing preferences (shortcut for Repeat Last Command, theming, etc.) can be edited in-app via the Preferences panel — see slots/maya/preferences.py.
Platform support
| DCC | Status |
|---|---|
| Maya 2025+ | Full — entry point, ~55 slot modules, all default menus wired. |
| Blender | Wrapper class only (TclBlender). No bundled slot library. |
| 3ds Max | Wrapper class only (TclMax). No bundled slot library. |
Contributions of Blender / Max slot suites are welcome.
Development
Clone and install in editable mode:
git clone https://github.com/m3trik/tentacle
pip install -e ./tentacle
Run the structural test suite:
cd tentacle
python -m pytest test/
The CI workflow (.github/workflows/tests.yml) runs:
test_package.py— package metadata sanitytest_slot_integrity.py— widget-name ↔ slot-method binding coveragetest_ui_integrity.py— UI/slot file pairing- Module-specific suites (e.g.
test_rendering.py)
For ad-hoc reproductions, drop scripts into test/temp_tests/ (gitignored from the regular run).
Further reading
API_REGISTRY.md— auto-generated, exhaustive list of every public class/method with file:line links.API_CHANGES.md— diff vs. previous registry refresh.CHANGELOG.md— notable behavioral and feature changes.CLAUDE.md— engineering conventions for contributors / agents.- Upstream packages — pythontk (utilities), uitk (Switchboard + MarkingMenu engine), mayatk (Maya helpers).
License
Tentacle is released under the LGPL v3.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tentacletk-0.10.80-py3-none-any.whl.
File metadata
- Download URL: tentacletk-0.10.80-py3-none-any.whl
- Upload date:
- Size: 243.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf8b1b47cf058adc5da05beaae8fafbd134a10303bde0258443f98a59d824cd3
|
|
| MD5 |
b984cfa2f9bf5300e52fc109be3e540e
|
|
| BLAKE2b-256 |
12d75cbeaeb80132d061228c13bad47f6af359c95fb58b97ebce10321a91c33e
|