0

I am trying to make a plug-in that loads a menu with a simple print command attached to a button. I got two files:

  1. test_menu.py
import maya.cmds as cmds import maya.mel as mel def say_hello(): print('hello') def menuui(): main_window = mel.eval("$retvalue = $gMainWindow;") custom_menu = cmds.menu('test_menu', label='test_menu', parent=main_window, tearOff=True) cmds.menuItem(label='say hello', command='say_hello()') cmds.setParent( '..', menu=True ) menuui() 
  1. test_plugin.py
import maya.cmds as cmds from maya.api import OpenMaya import os maya_useNewAPI = True def load_menu(script_path): if os.path.isfile(script_path): with open(script_path) as f: exec(f.read(), globals()) def unload_menu(): cmds.deleteUI(cmds.menu('test_menu', e=True, deleteAllItems=True)) def initializePlugin(plugin): plugin_fn = OpenMaya.MFnPlugin(plugin) load_menu("C:/Users/Roger/Documents/maya/scripts/test_menu.py") def uninitializePlugin(plugin): plugin_fn = OpenMaya.MFnPlugin(plugin) unload_menu() 

When the test_menu.py is executed within the 'Script Editor' it works as expected. But, when executed as a plug-in it only loads the menu but when pressing the button it returns: # Error: NameError: file line 1: name 'say_hello' is not defined # .

It seems as if when loading the plugin maya executes it outside the scene?

The only workaround i've found. Which is quite horrible tbh is to add import test_menu before executing the command.

cmds.menuItem(label='say hello', command='import test_menu; say_hello()') 

I would appreciate any help :)

1
  • I'd say the solution you found is not horrible but the normal solution with python if you cannot import your menu script into the plugin script. You wrote a python module and then you import it and create your menu. I'd rather impor in your plugin script and call it from there. Your first way to load a fiel and run it with the exec() command is a very unusual way. Commented Jul 9, 2023 at 14:38

1 Answer 1

0

The way I've dealt with custom plug-ins in Maya, is to use a module file.

In the Maya preferences folder, you need a plug-ins folder as well as a modules folder (just create them if they don't exist).

File structure

As an example, let's make a plug-in called foo. Start by creating the following file structure

modules/ foo.mod plug-ins/ foo.py modules/ __init__.py menu.py 

Edit the files

foo.mod

+ PLATFORM:win64 Foo 1.0 ..\plug-ins\foo MAYA_PLUG_IN_PATH +:= + PLATFORM:mac Foo 1.0 ../plug-ins/foo MAYA_PLUG_IN_PATH +:= + PLATFORM:linux Foo 1.0 ../plug-ins/foo MAYA_PLUG_IN_PATH +:= 

foo.py

import maya.api.OpenMaya as om import maya.cmds as cmds import modules.menu as menu def maya_useNewAPI(): pass def initializePlugin(plugin): plugin_fn = om.MFnPlugin(plugin, 'RogerP', '1.0', 'Any') menu.create_menu() def uninitializePlugin(plugin): menu.destroy_menu() 

modules/menu.py

import maya.cmds as cmds import maya.mel as mel def create_menu(): main_window = mel.eval('$tmpVar=$gMainWindow') menu = cmds.menu('foo', label='foo', parent=main_window, tearOff=True) cmds.menuItem(label='Print Hello', command=print_command) cmds.setParent('..', menu=True) def destroy_menu(): if cmds.menu('foo', exists=True): cmds.deleteUI('foo', menu=True) # also deletes children def print_command(*args): print('Hello') 

Note that the command argument uses a reference to the print_command and NOT a string 'print_command()'. You can use partial if you want to pass arguments.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.