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

Maya Python工具包开发:多行按钮命令格式化技巧问询

解决Maya Python按钮命令的缩进与可读性问题

嘿,我完全懂你现在的困扰——在写Maya工具的按钮命令时,用三引号包多行代码却不得不删掉所有缩进才能避免unexpected indentation错误,代码瞬间变得乱糟糟的,可读性大打折扣。别急,这里有几个实用的技巧帮你搞定这个问题:

技巧1:用textwrap.dedent()自动清理多余缩进

Python的textwrap模块里的dedent()方法可以自动移除所有代码行共同的前导空白,这样你就能在保持代码缩进格式的同时,避免Maya解析字符串时的缩进错误。

用法很简单,先导入模块,然后把你的三引号字符串用dedent()包裹,注意要在三引号前加一个反斜杠\来去掉第一行的空行:

import textwrap
import maya.cmds as cmds

form = cmds.formLayout(numberOfDivisions=3)
add_button = cmds.button(label="Add Selected", command=textwrap.dedent("""\
    selection = cmds.ls(sl=True)
    list_label = cmds.text('attachToList', query=True, label=True)
    split_list = list_label.split(', ')
    split_list[0] = split_list[0].replace('Attach to: ', '')
    list_items = split_list
    for each in selection:
        if not each in list_items:
            list_items.append(each)
    list_items = [item for item in list_items if item != ""]
    cmds.text('attachToList', edit=True, label='Attach to: ' + ', '.join(list_items))
"""))

# 其他按钮同理处理
remove_button = cmds.button(label="Remove Selected", command=textwrap.dedent("""\
    selection = cmds.ls(sl=True)
    list_label = cmds.text('attachToList', query=True, label=True)
    split_list = list_label.split(', ')
    split_list[0] = split_list[0].replace('Attach to: ', '')
    list_items = split_list
    for each in selection:
        if each in list_items:
            list_items.remove(each)
    cmds.text('attachToList', edit=True, label='Attach to: ' + ', '.join(list_items))
"""))

clear_button = cmds.button(label="Clear", command="cmds.text('attachToList', edit=True, label='Attach to: ')")
cmds.formLayout(form, edit=True, attachForm=[(add_button, "left", 5), (clear_button, "right", 5)], attachPosition=[(add_button, "right", 2, 1), (remove_button, "left", 2, 1), (remove_button, "right", 2, 2), (clear_button, "left", 2, 2)])
cmds.setParent("..")

技巧2:改用函数/ lambda(更推荐的最佳实践)

其实Maya的button命令的command参数不止能接受字符串,还能直接传入函数对象——这才是更规范、更易维护的写法,完全不用再纠结字符串缩进的问题,代码逻辑也更清晰。

比如把按钮的逻辑封装成独立的函数,然后直接把函数名传给command参数:

import maya.cmds as cmds

def handle_add_selected(*args):
    # 这里保持正常的代码缩进,可读性拉满
    selection = cmds.ls(sl=True)
    list_label = cmds.text('attachToList', query=True, label=True)
    split_list = list_label.split(', ')
    split_list[0] = split_list[0].replace('Attach to: ', '')
    # 建议用copy避免修改原列表,防止意外bug
    list_items = split_list.copy()
    
    for each in selection:
        if each not in list_items:
            list_items.append(each)
    # 用列表推导式简化空字符串过滤逻辑
    list_items = [item for item in list_items if item]
    
    cmds.text('attachToList', edit=True, label='Attach to: ' + ', '.join(list_items))

def handle_remove_selected(*args):
    selection = cmds.ls(sl=True)
    list_label = cmds.text('attachToList', query=True, label=True)
    split_list = list_label.split(', ')
    split_list[0] = split_list[0].replace('Attach to: ', '')
    list_items = split_list.copy()
    
    for each in selection:
        if each in list_items:
            list_items.remove(each)
    
    cmds.text('attachToList', edit=True, label='Attach to: ' + ', '.join(list_items))

form = cmds.formLayout(numberOfDivisions=3)
# 直接传入函数名即可,不用加引号
add_button = cmds.button(label="Add Selected", command=handle_add_selected)
remove_button = cmds.button(label="Remove Selected", command=handle_remove_selected)
clear_button = cmds.button(label="Clear", command=lambda *args: cmds.text('attachToList', edit=True, label='Attach to: '))

cmds.formLayout(form, edit=True, attachForm=[(add_button, "left", 5), (clear_button, "right", 5)], attachPosition=[(add_button, "right", 2, 1), (remove_button, "left", 2, 1), (remove_button, "right", 2, 2), (clear_button, "left", 2, 2)])
cmds.setParent("..")

这里要注意:Maya会在触发按钮时给回调函数传递一个参数(按钮的名称),所以我们的函数要加*args来接收这个参数,避免报错。对于简单的逻辑,也可以用lambda来快速定义(比如上面的Clear按钮)。

这种方式的优势很明显:代码结构清晰、缩进正常、逻辑可以复用(比如你可以提取出解析列表标签的公共函数),还能避免字符串解析带来的潜在问题(比如变量名冲突、特殊字符转义等)。

总结

  • 如果只是临时快速调整,textwrap.dedent()能快速解决缩进问题;
  • 长期来看,使用函数作为回调是Maya工具开发的最佳实践,代码更易维护和调试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 09:47:31