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

Maya脚本需求:选中新对象弹出专属重选对话框及代码调试

实现Maya选中对象时弹出专属重选对话框

我明白你想要的效果:每次在Maya里选中一个新对象,就弹出一个专属窗口,点击窗口里的按钮就能重新选中这个对象。你的思路(用类来封装每个对象的窗口逻辑)是完全正确的,但现有代码缺少选择事件监听和正确的方法绑定,我来帮你修正并完善这个功能。

先说说你现有代码的几个核心问题:

  • 没有监听Maya的选择变化事件,代码只会一次性执行,无法在每次选中新对象时触发
  • 按钮的命令('sel_obj()')是字符串形式,无法访问Person类里的实例方法
  • 重复导入了maya.cmds,也没处理重复选择同一个对象、对象被删除的边界情况

修正后的完整代码

import maya.cmds as cm

# 记录已创建的窗口,避免同一个对象重复弹出窗口
existing_windows = {}

class ObjectSelectorWindow:
    def __init__(self, obj_name):
        self.obj_name = obj_name
        # 用对象的唯一长名称作为窗口名,防止重名对象导致的冲突
        self.window_name = f"ObjSelector_{obj_name}"
        
        # 如果窗口已存在,先关闭再重建(也可以改成直接激活窗口,看你需求)
        if cm.window(self.window_name, exists=True):
            cm.deleteUI(self.window_name)
            
        # 创建窗口UI
        self.window = cm.window(self.window_name, title=f"Select {obj_name.split('|')[-1]}", bgc=(0.47, 0.53, 0.46))
        cm.columnLayout(cw=180, cat=('both', 12))
        
        cm.separator(height=15, style='none')
        cm.text(f"Target Object: {obj_name.split('|')[-1]}", fn='boldLabelFont', align='center')
        cm.separator(height=10, style='none')
        # 用lambda绑定实例方法,确保按钮能正确调用到当前对象的选中逻辑
        cm.button(label='Re-select This Object', command=lambda *args: self.select_target(), bgc=(0.6, 0.7, 0.6))
        cm.separator(height=10, style='none')
        
        cm.showWindow(self.window)
        # 把窗口名存入字典,方便后续检查
        existing_windows[obj_name] = self.window_name

    def select_target(self):
        # 先检查对象是否还存在,避免Maya报错
        if cm.objExists(self.obj_name):
            cm.select(self.obj_name, replace=True)
        else:
            cm.warning(f"对象 {self.obj_name.split('|')[-1]} 已被删除!")
            # 对象不存在时自动关闭窗口并清理记录
            cm.deleteUI(self.window_name)
            del existing_windows[self.obj_name]

def handle_selection_change():
    # 获取当前选中的对象,这里只处理单个对象的情况(你可以根据需求修改为多选逻辑)
    selected_objs = cm.ls(selection=True, long=True)  # 用长名称避免重名问题
    if len(selected_objs) == 1:
        target_obj = selected_objs[0]
        # 如果这个对象的窗口还没创建,或者窗口已被关闭,就新建窗口
        if target_obj not in existing_windows or not cm.window(existing_windows[target_obj], exists=True):
            ObjectSelectorWindow(target_obj)
    # 如果你想处理多选/空选的情况,可以在这里添加对应逻辑

# 创建脚本作业,监听Maya的选择变化事件
# 注意:如果要停止监听,执行 cm.scriptJob(kill=selection_job_id) 即可
selection_job_id = cm.scriptJob(event=["SelectionChanged", handle_selection_change], protected=True)

print(f"选择监听已启动,作业ID: {selection_job_id}")

关键功能说明:

  1. 选择事件监听:用cm.scriptJob监听SelectionChanged事件,每次用户切换选中对象时,都会自动触发handle_selection_change函数。
  2. 窗口唯一性:用对象的长名称作为窗口的唯一标识,避免重名对象导致的窗口混乱,同时防止同一个对象重复弹出窗口。
  3. 方法正确绑定:用lambda把实例的select_target方法绑定到按钮,确保点击按钮时能准确选中当前窗口对应的对象。
  4. 容错处理:在选中对象前检查对象是否存在,如果对象已被删除,会弹出警告并自动关闭窗口,避免Maya报错。

使用方法:

把这段代码复制到Maya的脚本编辑器里运行,之后每次你选中单个对象时,就会弹出对应的专属窗口;点击窗口里的按钮,就能重新选中这个对象。如果对象被删除,窗口会自动关闭。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:42:37