Maya - Python 3 - 用户界面的“未找到对象”错误
我开始学习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()
解决方案
你的代码里有几个问题:
- 当
do_set_interval被调用时,实际传入的是该控件的值,而不是控件的名称。 - 变量
bake_on_ifg超出作用域,因此如果你想在其他地方访问它,必须把它改为global,或把你的函数封装在一个class中。 - 当你查询
intFieldGrp时,可以获得最多四个值的列表(value=True),或者请求这四个可能值中的一个(value1=True、value2=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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。