试图将变量传递给函数内的函数。 - Python

时间:2016-10-22 23:31:33

标签: python maya

由于某些限制,我不能像往常那样使用一个类。

我需要传递一个函数变量,但该函数在另一个函数内部。

这是我使用的代码,请温柔,我不是蟒蛇巫师,而且我是自学成才。我遇到的问题是nButtons在我的函数reColor中返回False。

import maya.cmds as cmds

nButtons = 4

def ColorMeButtonsUI(nButtons):
    def reColor(nButtons):
        for i in range(nButtons):
            cmds.button(str(i), edit = True, bgc = (1,1,1))

    if cmds.window('colorUI', exists= True):
        cmds.deleteUI('colorUI')

    if not nButtons:
        nButtons = 3

    if nButtons >= 2 and nButtons < 10:
        colorUI = cmds.window('colorUI', title='Color me, Buttons', widthHeight=(200, 55), rtf = True  )
        cmds.columnLayout( adjustableColumn=True)
        cmds.button('Color', label='Color', command = reColor)
        for i in range(nButtons):
            cmds.button(str(i), label = 'Color'+str(i+1))
        cmds.setParent( '..' )
        cmds.showWindow( colorUI )
    else:
        cmds.error ('Input is invalid. Please confirm input >1 and <10')
    return nButtons

ColorMeButtonsUI(nButtons)

编辑:该命令由GUI按钮运行:cmds.button('Color', label='Color', command = reColor)

3 个答案:

答案 0 :(得分:0)

欢迎来到stackoverflow,你已经尝试过不要重复自己并迭代一个范围来编辑bgc,很好。但是像你通常那样使用类,尝试使用库Dictionary来创建你的ui元素,并使用ui dag路径调用它。实例迭代您将迭代dict项目的范围,并提供更多信息以便处理。

import maya.cmds as cmds
nButtons = 5
# create a dict for the buttons
ui_dict  = {}
def ColorMeButtonsUI(nButtons):
    def reColor(*args):
        # iterate the dict with the created buttons inside 
        for ui_id, ui_dag in ui_dict.iteritems():
            print ui_id, ui_dag
            # and edit ther color
            cmds.button(ui_dag, edit = True, bgc = (1,1,1))
            # you can also search for ids eg:
            if str(2) in str(ui_id):
               print ui_dag

    if cmds.window('colorUI', exists= True):
        cmds.deleteUI('colorUI')

    if not nButtons:
        nButtons = 3
    # you can also use
    # if 10>nButtons>= 2:
    if nButtons >= 2 and nButtons < 10:
        colorUI = cmds.window('colorUI', title='Color me, Buttons', widthHeight=(200, 55), rtf = True  )
        cmds.columnLayout( adjustableColumn=True)
        cmds.button('Color', label='Color', command = reColor)
        #use the range start,end 
        for i in range(1,nButtons):
            #create a relativ linking instance hard coded ids
            #add element to dict 
            # we stay on your case and add the index too(not more needed except searching)
            ui_dict[(i)] = cmds.button(label = 'Color'+str(i))
        cmds.setParent( '..' )
        cmds.showWindow( colorUI )
    else:
        cmds.error ('Input is invalid. Please confirm input >1 and <10')
    return nButtons

ColorMeButtonsUI(nButtons)

答案 1 :(得分:0)

我建议你避免在另一个函数中创建一个函数。

如果你在外面添加这个功能:

def reColor(nButtons):
        for i in range(nButtons):
            cmds.button(str(i), edit = True, bgc = (1,1,1))


def ColorMeButtonsUI(nButtons): 
(...)

您可以在ColorMeButtonsUI中使用reColor。

另外,请注意,除非使用

,否则无法发送参数(在本例中为nButtons)通过按钮调用命令
from functools import partial

然后在该命令参数上使用partial()。 我建议你阅读this other post

我的建议,仅供记录:

  • 观看身份。每个身份级别有4个空格。没有标签。
  • 不要使用大写字母来定义函数。仅适用于班级名称。所以它应该是&#34; colorMeButtonsUI&#34;。
  • 如果你只想在colorMeButtons中使用reColor,你可以改为调用它__reColor(nButtons),这样它就是私有的(不是完全私有的,因为Python没有这样的东西,只是隐藏了列表中的函数名称)此文件的可用组件)。或者只是带有一个下划线的_reColor,注意这个函数只能在这个文件中使用。

答案 2 :(得分:0)

问题与Python处理循环变量的方式有关。当您尝试在循环中创建某些内容时,Python会为您记住循环变量(这在技术上是closure)。

通常这很方便 - 但是在循环中,闭包将始终记住循环的最后一个值,而不是循环运行时所需的值。所以如果你尝试过这样明显的东西:

for n in range (nbuttons):
    def button_func (*_):
        print "color", n
   cmds.button(label = "color %i" %n, c = button_func)

您正确地将标记为 - 但是他们都会打印出nbuttons的值,因为关闭会在循环结束时发生。这绝对令人困惑。

关闭的规则是它们在范围结束时发生。所以你只需要通过创建一个子函数(创建自己的范围)并从循环中调用该函数来提前发生。因此:

def ButtonUI(nbuttons =3):

    colorUI = cmds.window(title='Color me, Buttons', widthHeight=(200, 55), rtf = True  )
    cmds.columnLayout( adjustableColumn=True)
    def generate_button(idx):
        def callback(*_):  # < will inherit the value of idx automatically
            print "color", idx
        cmds.button(label = 'color %i' %idx, c = callback)

    for n in range(1, nbuttons +1):
        generate_button(n)
    cmds.showWindow(colorUI)

在此安排中generate_button将获取idx的值并将其与私有callback函数正确配对,因此每个按钮将打印出与其标签相同的索引值。子子函数使用闭包来存储正确的值。您可以使用functools.partial对象执行相同的操作,但是一旦您看到闭包的工作方式是不必要的。

有关在循环中创建UI的更多信息here