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

Maya 2022函数嵌套调用及GUI按钮报错问题求助

Maya GUI开发问题:单选按钮与Create按钮交互报错

我正在Maya中开发一款GUI,用于生成程序化材质或基于用户输入纹理文件的材质。目前代码里有大量占位内容,核心需求是实现Create按钮根据选中的单选按钮打印不同内容。我熟悉PyQt5开发,但刚接触Maya GUI。

运行当前代码时出现报错:

Error: RuntimeError: file line 87: Object '<main.Custom_Shader_Window object at 0x0000019CBB34E648>' not found.

尝试相关调试后仍未解决,恳请提供帮助与建议。

当前代码

import maya.cmds as cmds

class Custom_Shader_Window(object):
        
    #constructor
    def __init__(self):

        self.window = "AR_Window"
        self.win_title = "Custom Shader"
        self.mat_title = "Material"
        self.attr_title = "Attributes"
        self.size = (400, 400)

        # close old window is open
        if cmds.window(self.window, exists = 1):
            cmds.deleteUI(self.window, window = 1)

        #create new window
        self.window = cmds.window(self.window, title = self.win_title, widthHeight = self.size)
        form = cmds.formLayout(numberOfDivisions=100)

        mat_title = cmds.text(self.mat_title)
        attr_title = cmds.text(self.attr_title)

        attrs = cmds.optionMenuGrp(cw = [1,10])
        cmds.menuItem(l = 'aiStandardSurface')
        cmds.menuItem(l = 'aiToon')
        cmds.menuItem(l = 'standardSurface')
        cmds.menuItem(l = 'Lambert')
        cmds.menuItem(l = 'Blinn')
        cmds.menuItem(l = 'Phong')
        cmds.menuItem(l = 'aiFlat')
        cmds.menuItem(parent=(attrs +'|OptionMenu'), label='Blue' )

        attr_list = cmds.textScrollList( numberOfRows=8, allowMultiSelection=True,
                                        append=['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
                                                'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen'],
                                        showIndexedItem = 1, w = 170)

        self.radio_butts = cmds.radioButtonGrp(la2 = ['Procedural', 'Texture Files'], nrb = 2, on1 = self.do_procedural,
                                          on2 = self.do_txt_f, an1 = 'Can work on any objects. Will add procedural noise textures that can be customized by the user.',
                                          an2 = 'Only works on objects with the same UVs. User can browse for desired texture files.')

        self.browse_field = cmds.textFieldButtonGrp(it = 'Texture File Here', bl = 'Browse', ann = 'Click "Browse" to search for texture file.', bc = self.do_browse_butt)

        create_butt = cmds.button(l = 'Create', w = 150, command = self.do_butt, aop = 1)

        help_txt = cmds.helpLine()

        cmds.formLayout(form, edit = 1, af = [(mat_title, 'top', 5), (mat_title, 'left', 100), (attr_title, 'top', 5),
                                              (attr_title, 'right', 100), (attrs, 'top', 50), (attrs, 'left', 5),
                                              (attr_list, 'top', 50), (attr_list, 'right', 5), (self.radio_butts, 'top', 150),
                                              (self.radio_butts, 'left', 100), (self.browse_field, 'bottom', 100),
                                              (self.browse_field, 'left', 50), (create_butt, 'bottom', 50),
                                              (create_butt, 'left', 5), (help_txt, 'left', 5), (help_txt, 'bottom', 20)])

        cmds.showWindow(self.window)
        
    def do_procedural(self, *args):
        print('Procedural')
        cmds.disable(self.browse_field)
        
    def do_txt_f(self, *args):
        print('Texture Files')
        cmds.disable(self.browse_field, v = 0)
        
    def do_browse_butt(self, *args):
        basicFilter = "All Files (*.*)"
        img_dir = cmds.fileDialog2(ff = basicFilter, dialogStyle=2, cap = 'test', fm = 1)
        print(img_dir)
        dir_split = img_dir[0].split("/")
        print(dir_split)
        img_file = dir_split[-1]
        print(img_file)
        
    def do_browse_txt(self, *args):
        basicFilter = "All Files (*.*)"
        img_dir = cmds.fileDialog2(ff = basicFilter, dialogStyle=2, cap = 'test', fm = 1, ocm = 'global proc MyCustomOptionsUICommit(test $formLayout)')
        
    def do_butt(test, self, *args):
        print('butt')
        self.radio_butts = cmds.radioButtonGrp(test, q=1, select=1)
        if self.radio_butts == 1:
            print('true')
        elif self.radio_butts == 2:
            print('false')



myWindow = Custom_Shader_Window()

问题原因与修复方案

1. 核心报错:方法参数顺序错误

do_butt方法的参数顺序完全颠倒了——类方法的第一个参数必须是self,而Maya回调会把控件名称作为第二个参数传入。原代码中def do_butt(test, self, *args):的写法导致self无法正确绑定到类实例,触发"Object not found"错误。

修复后的do_butt方法:

def do_butt(self, test, *args):
    print('Create按钮被点击')
    selected_radio = cmds.radioButtonGrp(self.radio_butts, q=True, select=True)
    if selected_radio == 1:
        print('已选择程序化材质')
    elif selected_radio == 2:
        print('已选择纹理文件材质')
  • 调整参数顺序,将self放在第一位
  • 保留初始化时保存的self.radio_butts控件ID,不要重新赋值,直接用它查询选中状态

2. 控件状态修改命令错误

原代码中使用的cmds.disable不是Maya标准命令,会触发报错,需要替换为对应控件的编辑命令:

def do_procedural(self, *args):
    print('Procedural')
    cmds.textFieldButtonGrp(self.browse_field, edit=True, enable=False)
    
def do_txt_f(self, *args):
    print('Texture Files')
    cmds.textFieldButtonGrp(self.browse_field, edit=True, enable=True)

3. 回调绑定的额外注意事项

如果后续遇到实例被垃圾回收的问题,可以用functools.partial显式绑定self,创建按钮时修改为:

from functools import partial

create_butt = cmds.button(l='Create', w=150, command=partial(self.do_butt), aop=1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:50:37