You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maya动态窗口模块化开发:批量导入与分类标签实现问询

Solution for Maya Modular Menu: Batch Module Import & Categorization

Hey Kenny, let's work through your two core challenges with your dynamic Maya menu—batch importing modules and organizing them into categories. This setup will keep your code clean, scalable, and easy to maintain. Here's how to do it:

1. Safe Batch Import of Modules in modList.py

We'll use Python's os and importlib modules to dynamically load all valid modules in the /modules folder, with error handling to prevent a single bad module from breaking the whole menu.

First, add this code to modList.py:

import os
import importlib
import maya.cmds as cmds

# Global registry to store modules by their category
module_registry = {}

def load_modules():
    """Dynamically load all valid modules in the same directory as modList.py"""
    # Get the path to the /modules folder (where this script lives)
    modules_dir = os.path.dirname(__file__)
    
    # Iterate over all files in the folder
    for filename in os.listdir(modules_dir):
        # Skip non-Python files, __init__.py, and this script itself
        if filename.endswith(".py") and filename not in ("__init__.py", "modList.py"):
            # Strip the .py extension to get the module name
            module_name = filename[:-3]
            try:
                # Dynamically import the module (adjust the package path if needed)
                # Assuming your /scripts/modularMenu is in Maya's script path
                module = importlib.import_module(f"modularMenu.modules.{module_name}")
                
                # Validate the module has required attributes (see section 2)
                if hasattr(module, "MODULE_CATEGORY") and hasattr(module, "build_ui"):
                    # Add the module to the registry under its category
                    if module.MODULE_CATEGORY not in module_registry:
                        module_registry[module.MODULE_CATEGORY] = []
                    module_registry[module.MODULE_CATEGORY].append(module)
                else:
                    print(f"Warning: Module '{module_name}' missing required attributes (MODULE_CATEGORY or build_ui)")
            except Exception as e:
                print(f"Failed to load module '{module_name}': {str(e)}")

2. Module Convention for Categorization

Each module (like mod1.py, mod2.py) needs to follow a simple, consistent convention so modList.py can recognize its category and render its UI. Here's a template for any module:

# mod1.py (example module)
import maya.cmds as cmds

# Required: Define the category this module belongs to
MODULE_CATEGORY = "Modeling Tools"

# Required: Define a function to build the module's UI elements
def build_ui(parent_layout):
    """Build UI elements for this module, attached to the parent layout"""
    # Example UI: A button that triggers the module's functionality
    cmds.button(
        parent=parent_layout,
        label="Mesh Cleanup Tool",
        command=lambda _: run_mesh_cleanup()
    )

# Module-specific functionality
def run_mesh_cleanup():
    cmds.polyCleanup()
    print("Mesh cleanup completed!")

3. Populate the Window with Categorized Modules

Update your populateWindow() function in modList.py to use the module_registry and render UI by category:

def populateWindow(parent_layout):
    """Populate the main window layout with categorized modules"""
    # Sort categories alphabetically for consistency
    for category in sorted(module_registry.keys()):
        # Create a collapsible frame for each category
        frame = cmds.frameLayout(
            parent=parent_layout,
            label=category,
            collapsable=True,
            collapse=False,
            borderVisible=True
        )
        # Create a layout inside the frame to hold module UI elements
        category_layout = cmds.columnLayout(
            parent=frame,
            adjustableColumn=True,
            rowSpacing=5
        )
        
        # Render each module's UI in the category
        for module in module_registry[category]:
            module.build_ui(category_layout)
        
        # Return to the parent layout to add the next category
        cmds.setParent(parent_layout)

4. Tie It All Together in modMenu.py

Make sure your menu window loads modules first, then populates the UI:

# modMenu.py
import maya.cmds as cmds
from modularMenu.modules import modList

def show_modular_menu():
    # Close existing window if it exists
    if cmds.window("modularMenuWindow", exists=True):
        cmds.deleteUI("modularMenuWindow")
    
    # Create the main window
    window = cmds.window(
        "modularMenuWindow",
        title="Dynamic Modular Menu",
        widthHeight=(400, 500),
        resizeToFitChildren=True
    )
    main_layout = cmds.columnLayout(adjustableColumn=True, rowSpacing=10)
    
    # Load all modules first
    modList.load_modules()
    # Populate the window with categorized UI
    modList.populateWindow(main_layout)
    
    cmds.showWindow(window)

# Run the menu when the script is executed directly
if __name__ == "__main__":
    show_modular_menu()

Key Notes for Success

  • Package Setup: Ensure /scripts/modularMenu has an empty __init__.py file to mark it as a Python package (required for importlib to find modules).
  • Maya Script Path: Make sure /scripts is in Maya's script path (you can check with cmds.internalVar(userScriptDir=True)).
  • Scalability: Adding new modules is as simple as dropping a new .py file in /modules that follows the MODULE_CATEGORY and build_ui convention—no changes needed to modList.py or modMenu.py.

Give this setup a spin, and you’ll have a robust, dynamic menu that organizes your tools automatically!

内容的提问来源于stack exchange,提问作者Kenny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:09:26