Storing data about tools for use in Maya

I have been tasked with reworking some of the code that loads custom scripts and other tools into a user’s Maya session. Basically, the user triggers the code which creates a series of menus in the main window with various tools as menu items. The old code was considered burdensome because Maya took a long time to launch. Plus, a lot of the custom tools are no longer in use and should be retired.

I decided to start with a clean slate. I thought I could just create a directory tree, and the code would use the various paths in the tree to determine menu names and which script goes into which menu. Unfortunately, I found out a lot of files should just be ignored (like init.py). Plus, I had situations where code was placed in odd locations. For example, a modeling tool would appear under the the Model menu. However, the script is located in the Utility folder. We have a Utility menu as well. I am reluctant to move that file because it is a module that other tools import.

The previous team was able to do this because information about the tools was stored in a database. The code would call the database and use the data to set up the menus. However, this is probably one of the reasons why the code was slow. It made multiple database calls.

I am now trying to decide between several options. I could go the database route again but just make one call (or as few calls as I can). Another option is to store the data in a file next to the code. I could use a CSV file. This has an added advantage of being easy to update. I could use SQLite as well. I am not sure if one is better than the other. Is reading a CSV file slower than querying a SQLite database file?

Any insight would be highly appreciated!

Python’s csv module is quite fast, especially if you’re just using it to hold a tree of menus. However, since menus are hierarchical, and you are going to want to be able to extend this data in an easy way, I would recommend storing the data in an .xml file and using cElementree to parse it. There are a bunch of tutorials for elementree and cElementree (the latter is just a faster version of elementree written in C++). Avoid xml.dom.minidom if you can it’s pretty quirky and slow.

Take a look at how C# .xaml files or PyQT/PySide .ui files are constructed and how they deal with hierarchical menu data. Note, I don’t recommend actually trying to use PyQT/PySide to actually draw the menus, I’m just saying you can look at them as an example of how other people have solved this problem.

C# XAML is probably a little simpler to find examples for:
https://wpftutorial.net/Menus.html

Walking xml trees recursively:

1 Like

You can also use json instead of xml.

mGui currently has a menu loader that loads from a yaml file. I also recently added support for loading shelves based on a json file, still need to merge the PR though.

or, you can just have a python module where you only build the shelf. Might not be your case specifically, but people separate code from the configuration too often, but plain code is often more efective than building a configuration, and a configuration interpreter. Going that direction, any additional features you want to build through configuration you have to abstract via code. Too complicated. Python code like below is much easier:


import my.custom.code.ui.shelfDsl as shelf
import module1
import module2

g = shelf.newMenuGroup("for building things")
g.addSimpleButton("build thing", module1.buildStuff)
g.addSimpleButton("build another thing ", module1.buildStuff_advanced_newest)

g = shelf.newMenuGroup("for animating things")
g.addSimpleButton("animate thing", module2.animStuff)
g.addSimpleButton("animate another thing ", module2.animStuff_advanced_newest)
g.addDropdown("more stuff")
g.addSubmenu()
g.addCheckbox()..


Imagine the above, but expressed as configuration (which handler method from which module to load), the custom code on top to interpret that configuration, dynamic module loading…

Prefer simple code.

our menus are stored as python modules, the menu items are stored as dictionaries, where key is the item name and value stores the keyword args for the menu.
when we startup maya we inspect the modules and pull the data structures and build the menus.

dead simple, 100% python, keeps the layout completely isolated from the tools.

All of these are great ideas! Right now I am testing using a XML document as per the first response to this thread. The results look promising!