Maya - Python 3 - 用户界面的“未找到对象”错误

编程语言 2026-07-11

我开始学习Python,目的是在Maya中开发绑定/动画工具(从3D动画转向技术动画)。我一直对写函数很在行,但过程性编程一直比较困难。

我在做一个用户界面,它有一个 intFieldGrp (bake_on_ifg),让用户通过输入一个数字并点击 Enter 来指定烘焙帧的采样。当按下 Enter 键来执行存储区间的命令时,出现如下错误:

RuntimeError: file line 127: Object 'x' not found.

(其中“x”是你在intFieldGrp中输入的数字)

不确定自己是不是遗漏了什么,恳请给出见解。

import maya.cmds as cmds

def do_set_interval(bake_on_ifg, *args):
    interval = cmds.intFieldGrp(bake_on_ifg, q=True, value=1)

def create_ui():
    window = cmds.window(title="Reverse FK Tool", width=260)
    main_layout = cmds.columnLayout(adjustableColumn=True)

    bake_on_ifg = cmds.intFieldGrp(label="Bake FK on", parent=main_layout, changeCommand=do_set_interval)     

    cmds.showWindow(window)

if __name__ == "__main__":
    create_ui()

解决方案

你的代码里有几个问题:

  1. do_set_interval 被调用时,实际传入的是该控件的值,而不是控件的名称。
  2. 变量 bake_on_ifg 超出作用域,因此如果你想在其他地方访问它,必须把它改为 global,或把你的函数封装在一个 class 中。
  3. 当你查询 intFieldGrp 时,可以获得最多四个值的列表(value=True),或者请求这四个可能值中的一个(value1=Truevalue2=True 等)

选项1:读取传入的值

只需在调用 changeCommand 时使用传入的值:

def do_set_interval(value):
    print(f"The value is: {value}")
    interval = value

选项2:使用全局变量

create_ui 函数内部把一个变量声明为 global,以使其可被 do_set_interval 访问。每次你想对 bake_on_ifg 进行写操作时,首先需要把它引用为 global;但读取时则并非必要。我不推荐这种做法,个人也限制对 global 变量的使用。

import maya.cmds as cmds


def do_set_interval(value):
    values = cmds.intFieldGrp(bake_on_ifg, q=True, value=True)
    interval = values[0]  # the first value
    print(f"interval is {interval}")

def create_ui():
    window = cmds.window(title="Reverse FK Tool", width=260)
    main_layout = cmds.columnLayout(adjustableColumn=True)

    global bake_on_ifg 
    bake_on_ifg = cmds.intFieldGrp(label="Bake FK on", parent=main_layout, changeCommand=do_set_interval)

    cmds.showWindow(window)

if __name__ == "__main__":
    create_ui()

选项3:使用类

为了让一组函数能够访问同一组变量,将它们放在一个 class 中是个不错的做法。如果你对类还不熟悉,我建议你开始学习,因为它们在涉及UI与数据管理的场景中非常有用。希望下面的示例能有点清晰。请注意使用的词 self,它指的是“类本身的实例”。

通过使用 self.interval 而不仅仅是在本地作用域内声明 interval,它也能被同一类中的其他函数访问。

import maya.cmds as cmds


class BakeFK:
    def __init__(self):
        self.bake_on_ifg = None
        self.interval = 0
        self.create_ui()

    def do_set_interval(self, value):
        values = cmds.intFieldGrp(self.bake_on_ifg, q=True, value=True)
        self.interval = values[0]  # the first value

        print(f"interval is {self.interval}")

    def create_ui(self):
        window = cmds.window(title="Reverse FK Tool", width=260)
        main_layout = cmds.columnLayout(adjustableColumn=True)

        self.bake_on_ifg = cmds.intFieldGrp(label="Bake FK on", parent=main_layout, changeCommand=self.do_set_interval)

        cmds.showWindow(window)


if __name__ == "__main__":
    # Create an instance of the BakeFK class in the global scope to avoid it
    # being garbage collected while the window is still alive
    global bakeFK
    bakeFK = BakeFK()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章