Error: AttributeError: file <maya console> line 65: 'OptionsWindow' object has no attribute 'int_offset' #

Error: AttributeError: file <maya console> line 65: 'OptionsWindow' object has no attribute 'int_offset' #

我在 Maya 中的 Python 代码的第 65 行的 pasteTheseKeys 方法中收到此错误:

self.offsetVal = mc.intFieldGrp(self.int_offset, q=True, value1=True)

pasteTheseKeys 在按下 "Paste Keys" 按钮时被调用。该关系在 commonButtons 方法中定义。

完整代码:

# Animation Copy Tool
# Bakari Holmes 5/2/2015
# This is designed to copy and existing animation
# from one rig to another and make the process easier
# with a simple UI
# !!!Make sure you select keyframes in the graph editor to have them displayed before pasting!!!

import maya.cmds as mc
import functools
import maya.mel as mm
import pprint

"""OptionsWindow is a class definition of the basic window class.
   The class is adding a set of controls to create a template
   that resembles Maya's built-in tool option windows."""

class OptionsWindow(object):
    #@classmethod
    def showUI(cls):
        win = cls()
        win.create()
        return win
    def __init__(self):
        self.window = "Animation Copy Tool"
        self.title = "Animation Copier"
        self.size = (546,350)
    def create(self):
        if mc.window(self.window,exists=True): 
            mc.deleteUI(self.window,window=True)

        self.window = mc.window(self.window, title=self.title,widthHeight=self.size,menuBar=True)
        self.mainForm = mc.formLayout(nd=100)
        self.commandMenu()
        self.commonButtons()
        self.optionsBorder = mc.tabLayout(scrollable=True,height=1)
        mc.formLayout(self.mainForm,e=True,attachForm=([self.optionsBorder,"top",0],[self.optionsBorder,"left",2],[self.optionsBorder,"right",2]),attachControl=([self.optionsBorder,"bottom",5,self.applyBtn]))
        self.optionsForm=mc.formLayout(nd=100)
        mc.tabLayout(self.optionsBorder,edit=True,tabLabel=(self.optionsForm,"Test"))
        self.displayOptions()
        self.tx_src = mc.textFieldGrp(label="Source Object", editable=False, text=sel[0])
        self.int_offset = mc.intFieldGrp(label="Frame Offset Amount", value1=0)
        mc.showWindow()

    def commandMenu(self):
        self.editMenu = mc.menu(label="Edit")
        self.editMenuSave = mc.menuItem(label="Save Settings",command=self.editMenuSaveCmd)
        self.editMenuReset = mc.menuItem(label="Reset Settings",command=self.editMenuResetCmd)
        self.helpMenu = mc.menu(label="Help")
        self.helpMenuItem = mc.menuItem(label="Help on %s"%(self.title),command=self.helpMenuCmd)
    def helpMenuCmd(self,*args):
        mc.launch(web="http://maya-python.com")
    def editMenuSaveCmd(self,*args):pass
    def editMenuResetCmd(self,*args):pass

    def applyBtnCmd(self,*args):pass
    def closeBtnCmd(self,*args):
        mc.deleteUI(self.window,window=True)

    #paste operation
    def pasteTheseKeys(self):
        self.offsetVal = mc.intFieldGrp(self.int_offset, q=True, value1=True)
        self.selObj_pasteKeys = mc.ls(sl=True)

        for objectQuant in selObj_pasteKeys:
            print objectQuant
            self.ct = mc.currentTime(query = True)
            self.t = self.ct + self.offsetVal
            mc.currentTime(self.t)
            # mc.selectKey(selObj_pasteKeys[objectQuant])
            mc.pasteKey(time=(self.t, self.t), f=(1.0,1.0), option="merge", copies=1, to=0, fo=0, vo=0)

    def commonButtons(self):
        self.commonBtnSize=(self.size[0]-18/3,26)
        self.acctionBtn=mc.button(label="Paste Keys", command = self.pasteTheseKeys(), height=self.commonBtnSize[1])

        self.closeBtn = mc.button(label="Close",height=self.commonBtnSize[1],command=self.closeBtnCmd)


        mc.formLayout(self.mainForm, e=True, attachForm=([self.acctionBtn,"left",5],
                                                     [self.acctionBtn,"bottom",5],
                                                     [self.closeBtn,"bottom",5],
                                                     [self.closeBtn,"right",5]),
                                         attachPosition=([self.acctionBtn,"right",1,33],
                                                         [self.closeBtn,"left",0,67]),
                                         #attachControl=([self.applyBtn,"left",4,self.acctionBtn],
                                                      #  [self.applyBtn,"right",4,self.closeBtn]),
                                         attachNone=([self.acctionBtn,"top"],
                                                     [self.closeBtn,"top"]))
    def displayOptions(self):pass

#########################    
# end of class definition
#########################

def keys_as_dictionary(channel):
    """return a dictionay of times:values for <channel>"""
    keys = mc.keyframe(channel, q=True, tc=True) or []
    values = mc.keyframe(channel, q=True, vc=True) or []
    return dict(zip(keys, values))

def channels(object):
    """return a dictionary of <plug>:<channel_dict> for each animated plug selected"""
    keys = mc.keyframe(object, sl=True, n=True, q=True)
    result = {}

    for k in keys:
        plugs = mc.listConnections(k, p=True)[0]
        result[plugs]= keys_as_dictionary(k)
    return result



copyAnim="copyAnim"

#store selected object info
sel = mc.ls(selection=True)
print sel

if (len(sel) != 1):
    mm.eval("warning Must select one animated object;")

else:
    mc.copyKey()
    win = OptionsWindow()
    win.create()

    pprint.pprint(channels(sel))

我一直在梳理这里关于属性错误和实例属性与 class 属性的其他条目,但我仍然很困惑为什么会收到此错误。

一般情况下,只有在第一次设置属性值后才能访问属性。无论属性是 class 属性还是实例属性,都是如此。

在这种特殊情况下,您似乎在首次设置属性 int_offset 之前尝试访问它。

分析您的代码表明,属性 int_offset 首先在方法 create() 的末尾设置,而在到达该行代码之前引用它。事实上,在方法 create() 的稍早一点,方法 commonButtons() 被调用,方法 commonButtons() 又调用方法 pasteTheseKeys(),它引用属性 int_offset,但尚未得到定义的机会。