Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Maya/Python:在循环生成的UI中创建唯一命令_Python_Loops_User Interface_Maya_Autodesk - Fatal编程技术网

Maya/Python:在循环生成的UI中创建唯一命令

Maya/Python:在循环生成的UI中创建唯一命令,python,loops,user-interface,maya,autodesk,Python,Loops,User Interface,Maya,Autodesk,在Autodesk Maya中,我根据用户要创建的楼层数(变量numFloors从intField中获取)动态创建UI。对于每一层,我想制作一个按钮,用于更改相机的高度以查看楼层(这是针对建筑物的)。我的问题是,我无法让viewFloor()函数知道按下哪个按钮来激活它。每次按钮都会经过最近的楼层,而不是特定的楼层 我知道为什么会发生这种情况,当创建按钮时,命令不会动态存储,因此当单击按钮时,命令会使用变量的最新实例,该实例应该是与变量numFloors相等的最后一层 for i in rang

在Autodesk Maya中,我根据用户要创建的楼层数(变量numFloors从intField中获取)动态创建UI。对于每一层,我想制作一个按钮,用于更改相机的高度以查看楼层(这是针对建筑物的)。我的问题是,我无法让viewFloor()函数知道按下哪个按钮来激活它。每次按钮都会经过最近的楼层,而不是特定的楼层

我知道为什么会发生这种情况,当创建按钮时,命令不会动态存储,因此当单击按钮时,命令会使用变量的最新实例,该实例应该是与变量numFloors相等的最后一层

for i in range(0, numFloors):
    floor = i
    btnName = 'floor'+str(floor)+'ViewBtn'
    btnLabel = "view Floor " + str(floor)
    btnCmdVar = str(floor)
    cmds.button(btnName, label= btnLabel, w=20, h=20, command=lambda 
    arg:self.viewFloor(btnCmdVar))

def viewFloor(self, arg):
    print "arg = " + str(arg)
因此,当numFloors=4时,无论按下哪个楼层按钮,viewFloor都将始终向其传递4。正如我所说,我知道为什么会发生这种情况,这个代码片段只是我创建一个代码片段的最佳尝试,它将传达我正在尝试做的事情。不幸的是,我不知道如何真正做到这一点

我的一些想法是:

一些复杂的setattr和getattr设置(但我不知道如何工作)

或者是一个scriptJob,它检测按钮何时被按下,并将特定按钮的名称传递给viewFloor函数(然后我可以从字符串中提取数字以获得楼层)。但是,在Maya Python文档中,我找不到按下按钮时发生的事件或条件的任何指示。因此,我无法创建scriptJob


如果有人能为我指出正确的方向(例如我可能需要的scriptJob标志或setattr getattr设置的示例)或任何其他解决方案,我将不胜感激,因为我没有受过足够的教育,甚至无法想象。提前感谢您的帮助

这是lambda工作方式的一个众所周知的问题:它被记录在案

您可以通过以下几种方式解决此问题:

使用
functools.partial
而不是lambda
functools.partial
是模块中的一个对象,它将可调用函数和参数绑定在一起。您可以像使用lambda一样使用它:

from functools import partial

 
for i in range(0, numFloors):
   floor = i
   btnName = 'floor'+str(floor)+'ViewBtn'
   btnLabel = "view Floor " + str(floor)
   cmd = partial(self.viewFloor, i)
   cmds.button(btnName, label= btnLabel, w=20, h=20, command=cmd)
服从某项职能 这里,嵌套函数def将以与lambda相同的方式捕获值——但是嵌套可以防止您看到的问题


顺便说一句,在这两种策略中,self.showFloor需要额外的参数来容纳按钮总是触发的额外布尔值。

这里,我想我会发布我如何解决这个问题,以防它对其他人有帮助。 Partial不是一个可行的选项,因为变量cmd(如示例中所示)仍将使用循环更新,因此每个按钮仍返回最后一层。 在Maya中创建动态生成的UI的问题在于,其UI命令是函数而不是类,这意味着您不能在命令中实际存储任何数据,只能传递它。幸运的是,有人走在我前面,将整个Maya UI命令重写为类。您可以在此处找到该库:

为该库编写的功能代码如下:

for i in range(0, numFloors):
    floor = i
    BTN= mGui.Button()
    BTN.data.[`floor`] = floor
    BTN.command = self.viewFloor

def viewFloor(self, defaultArg, **kw):
    floor = str(kw[`floor`])
for i in range(0, numFloors):
    floor = i
    BTN= mGui.Button()
    BTN.data.[`floor`] = floor
    BTN.command = self.viewFloor

def viewFloor(self, defaultArg, **kw):
    floor = str(kw[`floor`])