Maya 2022执行Python脚本崩溃:菜单增删触发致命错误
问题分析
反复执行菜单添加/移除操作导致Maya崩溃,核心原因是每次调用newItem()时都会新建一个带optionBox的removeItem菜单项,而非复用已有控件。多次操作后菜单中堆积大量重复UI元素,触发Maya UI系统的底层冲突,最终导致致命错误。
解决方案
不要每次添加时重建移除按钮,而是提前创建好移除控件,通过显示/隐藏控制它的状态;同时避免使用字符串形式的命令绑定,改用直接函数引用,减少命名空间冲突风险。
修正后的代码:
import pymel.core as pm # 获取主窗口 main_window = pm.language.melGlobals['gMainWindow'] # 初始化UI元素容器 ui_elements = { 'custom_menu': None, 'sub_menu': None, 'add_item_btn': None, 'added_item': None, 'remove_item_btn': None } def setup_menu(): # 创建主菜单 ui_elements['custom_menu'] = pm.menu('Custom_Menu', parent=main_window, tearOff=True) # 创建子菜单 ui_elements['sub_menu'] = pm.menuItem(label="Menu Item 1", parent=ui_elements['custom_menu'], subMenu=True) # 添加按钮(带optionBox) pm.menuItem(label="Click Me", parent=ui_elements['sub_menu']) ui_elements['add_item_btn'] = pm.menuItem( label="Add Item", parent=ui_elements['sub_menu'], optionBox=True, command=lambda *args: add_item() ) # 提前创建移除按钮,默认隐藏 ui_elements['remove_item_btn'] = pm.menuItem( label="Remove Item", parent=ui_elements['custom_menu'], optionBox=True, command=lambda *args: remove_item(), visible=False ) def add_item(): if not ui_elements['added_item'] or not pm.objExists(ui_elements['added_item']): # 创建要添加的菜单项 ui_elements['added_item'] = pm.menuItem(label="Click Me", parent=ui_elements['custom_menu']) # 显示移除按钮 pm.menuItem(ui_elements['remove_item_btn'], edit=True, visible=True) else: print("Item already exists") def remove_item(): if ui_elements['added_item'] and pm.objExists(ui_elements['added_item']): pm.deleteUI(ui_elements['added_item'], control=True) ui_elements['added_item'] = None # 隐藏移除按钮 pm.menuItem(ui_elements['remove_item_btn'], edit=True, visible=False) print("Item removed") # 初始化菜单 setup_menu()
关键改进点
- 复用控件而非重建:移除按钮提前创建,通过
visible属性控制显示/隐藏,避免重复创建UI元素 - 避免字符串命令:用
lambda直接绑定函数,消除MEL与Python命名空间的潜在冲突 - 集中管理UI元素:用字典统一存储所有UI控件引用,避免全局变量混乱
- 存在性检查:操作前用
pm.objExists()验证控件是否有效,防止无效引用触发错误
内容的提问来源于stack exchange,提问作者aNup
相关产品推荐
相关产品推荐

