Maya python UI - 在同一函数内使用按钮命令时出现局部变量未定义错误

Maya python UI - local variable not defined error when used inside button command within same function

我正在学习如何在原生 python(不是 Tkinter)中为 Maya 构建 UI。下面的代码工作正常,创建一个 window 和一个按钮,当按下该按钮时将 'bar' 打印到历史输出:

import maya.cmds as cmds
cmds.window(title='Basic UI')
cmds.columnLayout()
foo = 'bar'
cmds.button(label = 'foobar', command = 'print(foo)')

cmds.showWindow()

但是如果我将相同的代码放在函数 buildIt() 中:

import maya.cmds as cmds

def buildIt():
    cmds.window(title='Basic UI')
    cmds.columnLayout()
    foo = 'bar'
    cmds.button(label = 'foobar', command = 'print(foo)')

    cmds.showWindow()

buildIt()

window 构建良好,但在激活按钮后我得到:

Error: NameError: file <maya console> line 1: name 'foo' is not defined

这里发生了什么?我该如何解决?

当您 运行 侦听器中的第一个样本时,foo 是在全局范围内定义的,因此在触发回调时可用。在第二个示例中,它是在函数范围内定义的——因此当回调在全局范围内触发时它不可用。

这会起作用:

import maya.cmds as cmds

def buildIt():
    cmds.window(title='Basic UI')
    cmds.columnLayout()
    foo = 'bar'
    def print_foo(*_):
        print foo
    cmds.button(label = 'foobar', command = print_foo)

    cmds.showWindow()

buildIt()

这里的区别是我们直接传递函数print_foo,而不是作为字符串。因此,Maya 在创建按钮时捕获它的值并保存它(这称为 closure,它非常有用)。这样可以保证在真正使用回调的时候可以使用函数。

一般来说,避免使用字符串版本的回调——它们是 MEL 的遗留物,它们总是会导致您所看到的问题。

更多详情here