Maya and Python and menus oh my!

Updated, was, “Multiple Python commands with Maya’s menuItem MEL”

Maya drives me nuts. I really wish I could spend my day in Houdini to see if it sucks less. Anyway, I digress. Python is awesome. Python’s integration with the rest of Maya is, well lacking.

I like to add my own ‘Pinkwerks’ menu to the main menu bar in Maya for ease of access to my favorite hacks. Turns out, you can’t add a custom menu to the main menu bar in Maya via as you would in userSetup.mel – It doesn’t seem to have access to the GUI when it’s evaluated during Maya’s start-up. Maybe someone can prove me wrong. So, I’m lamely forced to writing my own menu for the main menu bar with classic MEL which looks something like this.

global string $gMainWindow;
setParent $gMainWindow;
global string $gPinkwerksMenu = "Pinkwerks";
menu -label "Pinkwerks" -allowOptionBoxes true -tearOff true $gPinkwerksMenu;
menuItem -label "My Fancy Command" -command "myFancyCommand";

Now, let’s bring the pain. You’ve written a Python script and you want to call that script from a menuItem (as in the last line in the above code). A couple of points.

If you write and put it in MAYA_SCRIPT_PATH it isn’t loaded automagically like a .mel. (You’ll recall that if you name a .mel with the same name as a global function, it’s automatically callable by Maya at run-time. For instance if you have a file ‘myNoise.mel’ in a directory in the MAYA_SCRIPT_PATH environment variable and it contains a function in the form of ‘global proc myNoise(…){…’ you can type ‘myNoise’ at the MEL prompt or script editor and Maya will ‘find’ it without having to source it first.

This means if you have a Python function ‘myPyFunk’ in (and it resides in your MAYA_SCRIPT_PATH) – you still have to ‘import foo’ before you can call foo.myPyFunk(). This is achieved like so:

menuItem -label "My Py Funk"
-c "python(\"import foo;foo.myPyFunk()\")";

One last method of calling Python scripts before I wrap this up. If you’re like me, you tend to write code in and external editor. In Maya, for ease of use you want something analogous to `source mySheet.mel’, which reloads the file and runs the main task. You can get away one-liner simple execution of python scripts like so from the Python prompt or script editor tab:


This trick is achieved by adding the 2 lines below to the end of your .py. This assumes you wrap the guts of your script in a function named ‘doit()’. The Python interpreter will automatically call the function ‘doit()’ when it parses this file during the execfile(). Note in this case, anything you type in the will be evaiuated with exec, so I tend to wrap everything in a function and don’t leave any `raw’ python lying about.

def doit():
for s in sel:

if __name__ == '__main__':

Unfortunately this process is less clean than MEL in terms of ease of integration, but not so bad once you get over the ‘gotchyas’. Personally, I’m digging PyMEL.

Easy right?