How to expose python commands to keyboard shortcuts in Max



Hi all,

I have some python tools that I want the user to be able to assign keyboard shortcuts to.

I have added these as menu items so they appear in the Customise User Interface by using MaxPlus.ActionFactory.Create.
However I can’t assign a keyboard shortcut to them under the Customise User Interface, it lists the commands and I can choose to assign a key but afterwards the ‘Remove’ button is still disabled and no shortcut works.
Even after saving the keyboards file it is not assigned.

I’m creating a action for each tool to it can be launch via the menus using:
# – create action definition for menu item
tool_action = MaxPlus.ActionFactory.Create(

Any ideas how to get this to work?
I can see ActionItem has a GetShortcutString but not a Set.
I’m using MaxPlus in Max 2018.4

Cheers all.


The easiest way would be to expose the functionality as functions and create regular macroscripts importing the module from MAXScript and then calling the function.


Thanks for the reply.
I was hoping to avoid macroscripts as we have kept the Max installation vanilla.


That doesn’t make sense, if you have custom Python tools in Max then the install isn’t vanilla anymore.

Are you wanting the shortcuts to open and close the tool or are you wanting the shortcuts to run specific functionality from within the tool?

For the former:
You need:

  1. Your Python code/module.
  2. An execution Python script that imports and opens/closes the tool.
  3. A wrapper macro script that imports said execution Python script from Maxscript, using Python.ExecuteFile “Path”.

For the latter:
You need:

  1. Your Python code/module.
  2. Maxscript function or struct that wraps the tools specific call. I recommend this as it gives one specific access point to the functionality in Maxscript, rather than requiring arbitrary Python imports throughout your Maxscript code.
  3. A macroscript that either calls the Maxscript wrapper function or wraps the Python code directly.

As far as I am aware, you always need a macroscript to be able to add a shortcut via the customise menu.


The installation is still vanilla in the sense that we don’t copy any files to the Max Program Files or My Docs folders.

The Instance of Max we run is from a batch file (hijacked shortcut) where we run a startup script and import our Python modules.

Currently I create a mainmenu and menuitems for all our python tools using MaxPlus.MenuBuilder and MaxPlus.ActionFactory.Create().
Some of the items launch tools and others run specific tool functions.

These all show up in the Customize User Interface dialog under all the Tabs and all function as expected (adding to toolbars, etc) apart from when assigning shortcuts.


Ahh right, fair enough.

It seems like you would have to have a way of deploying the Python scripts to each PC, either via a network or over a version control system like Perforce, right?

I will say that MaxPlus is notoriously short on features and for most solutions will only get you 80% of the way there.

Our tools deployment works as follows:
A Python installer script adds custom paths to Additional Macros, Additional Startup Scripts and to the 3rd Party Plugins in 3dsmax.ini and Plugin.UserSettings.ini. This is run once when installing the tools.
All our Macros are stored in the Macros path, all api/functionality scripts are stored in the 3rd Party Plugins path and there is one startup script that does all our setup.
The main point of interest for this thread is our deployment of our Python tools; they follow the basic steps above, Python module > Python “MacroScript” importing and executing the Python Module > MacroScript importing the Python MacroScript via Maxscript.
The key thing is the Python MacroScripts are procedurally generated on startup, removing redundant ones and generating new ones as required.
We then have a menu generation script that creates a menu procedurally based on the folder structure of the MacroScripts path. This uses maxscripts MenuMan, which can be accessed via pymxs.runtime.menuman if you are on >= Max 2017 , MaxScript if < 2017.

The minimum I think you could do here is to modify your batch script to update the 3dsmax.ini and the Plugin.UserSettings.ini to include a path to your Macros and Startup Scripts, stored where ever you are storing your Python scripts, and write a startup script to generate procedural MacrosScripts and Menu.

That is the best I can offer as I doubt MaxPlus will get you where you want to go.

This might be a helpful thread to read as it touches some of the same topics: