#NameError:全局名称' time1'没有定义#maya-python

时间:2013-08-03 20:28:04

标签: python global maya

这是我的代码:

def animate(*arg):
    cvList = []
    myList = cm.ls(sl =True)
    randList1 = [rand.uniform(-10,10)for items in range(10)]
    for i in myList:
        cvList = cm.ls(i+".cv[:]" , flatten = True)
    for j in cvList:
        cm.setKeyframe(j , ".cv[0].xValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].xValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].yValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].yValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].zValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].zValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].xValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].xValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].yValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].yValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].zValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].zValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )


animWindow = cm.window(t = 'Animation controls' , w = 150 , menuBar = True , bgc = [.2,.2,.2])
cm.menu(l = 'About' , tearOff = False )
cm.menuItem( l = 'Version 1.0.0')
cm.columnLayout()
cm.text(l = 'Time 1' , w = 150)
time1 = cm.intField()
cm.text(l = 'Time 2' , w = 150)
time = cm.intField()
cm.button(l = 'Set key' , c = animate , w = 150, bgc = [.3,.3,.3])
cm.showWindow(animWindow)

这是我得到的错误:

# NameError: global name 'time1' is not defined #

我知道之后maya想告诉我time2是一样的

我在这个中使用了它并且它起作用了:

def tinyRandomize(*arg):
    myList = cm.ls (sl = True)
    randoms = [rand.uniform(cm.floatField(Ceil, q = True , v = True),0.5)for i in range(30)]
    for objects in myList:
        cm.xform('%s.cv[0]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[1]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[2]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[3]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[4]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[5]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[6]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[7]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[8]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[9]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[10]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[11]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[12]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[13]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[14]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[15]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[16]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[17]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[18]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[19]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])
        cm.xform('%s.cv[20]'%objects , r = True , t = [(rand.choice(randoms)),(rand.choice(randoms)),(rand.choice(randoms))])

我为这个def添加了一个gui,它完全有效

请帮帮我。

最好的问候

2 个答案:

答案 0 :(得分:0)

我发现在使用默认的maya UI元素创建简单接口时,使用类更简单,更简洁,更简洁。当在 init ()中定义时,它们会立即被调用,并且您的接口对象现在位于本地范围内。

import maya.cmds as cm
import random as rand

class RandomAnimation():
    def __init__():
        self.animWindow = cm.window(t = 'Animation controls' , w = 150 , menuBar = True , bgc = [.2,.2,.2])
        cm.menu(l = 'About' , tearOff = False )
        cm.menuItem( l = 'Version 1.0.0')
        self.cLayout = cm.columnLayout()
        self.timeText = cm.text(l = 'Time 1' , w = 150)
        self.time1 = cm.intField()
        self.cm.text(l = 'Time 2' , w = 150)
        self.time = cm.intField()
        self.myButton = cm.button(l = 'Set key' , c = self.animate , w = 150, bgc = [.3,.3,.3])
        cm.showWindow(animWindow)
        # Since the ui is in __init__() it will be ran once the class is instantiated.. 

    def animate(*args):
        # This will gather all of the cvs in all of your selected curves..
        for cv in [for j in [cm.ls(i + ".cv[:]", fl=1) for i in cm.ls(sl=True)]:
            # This will move all the cvs randomly..
            cm.xform(cv, r=1, t=[rand.uniform(-1, 1), rand.uniform(-1, 1), rand.uniform(-1, 1)])

检查this以获得有关课程的更全面的解释。

答案 1 :(得分:0)

您在def animate 之外声明了变量 time1 。当函数尝试运行时,它不知道time1是什么。

@ Argiri的答案是长期的正确方法 - 将UI和回调函数放入类中是一种更清晰,更好的组织代码的方法。

为了明确导致问题的原因,请尝试以下方法:

from functools import partial
import random as rand

def animate(time1, time2, ignore):
    print time1, time2, ignore
    cvList = []
    myList = cm.ls(sl =True)
    randList1 = [rand.uniform(-10,10)for items in range(10)]
    for i in myList:
        cvList = cm.ls(i+".cv[:]" , flatten = True)
    for j in cvList:
        cm.setKeyframe(j , ".cv[0].xValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].xValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].yValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].yValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].zValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[0].zValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].xValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].xValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].yValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].yValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].zValue" , t = cm.intField(time1 , query = True , value = True) , v = rand.choice(randList1) )
        cm.setKeyframe(j , ".cv[1].zValue" , t = cm.intField(time2 , query = True , value = True) , v = rand.choice(randList1) )


animWindow = cm.window(t = 'Animation controls' , w = 150 , menuBar = True , bgc = [.2,.2,.2])
cm.menu(l = 'About' , tearOff = False )
cm.menuItem( l = 'Version 1.0.0')
cm.columnLayout()
cm.text(l = 'Time 1' , w = 150)
time1 = cm.intField()
cm.text(l = 'Time 2' , w = 150)
time2 = cm.intField()
cm.button(l = 'Set key' , c = partial(animate, time1, time2) , w = 150, bgc = [.3,.3,.3])
cm.showWindow(animWindow)

模块 functools 包含一个名为 partial 的对象,它将一组参数与函数捆绑在一起,以便可以一起调用它们。通过在代码运行时将button命令设置为partial,您可以确保在运行回调时intField对象将转到函数 - 所以当def询问两个字段时它们是什么它知道如何找到他们。

所有这一切,使用类来做这样的事情。如果你不清楚课程需要花几天时间做maya的东西来学习它们 - 这对你未来代码的质量非常重要。

你应该在Maya python上查看Mechtley's book(尤其是关于GUI代码的章节)。还有一些有用的讨论hereherehere

PS:有人可能会发布一个修复,它将'全局'放在time1和time2之前,'global time1,time2'放在animate def中。 不要这样做。 Globals = evil。