PDA

View Full Version : How to set Button Params in a loop?


EightBit
01-11-2011, 08:01 AM
I'm writing a script which loads user-defined attrs (sliders) into a UI panel. I need to be able to select them as well, so I add a button for each one.
As I parse the UD attrs for a given object, I setup the name of the attr as a string and create an attrFieldSliderGrp and a button. The attrFieldSliderGrp works fine, however the button params all get updated with each iteration and then they all end up passing the name of the last attr in the list - in this case they all pass the name of the last attr (browsDown) to selectMe().

sel=cmds.ls(sl=1)
if len(sel) == 0:
mel.error("You must have an object selected!")

for obj in sel:
attributes=cmds.listAttr(obj, ud=1)

cmds.setParent('frameBegin')
sliderContainer = cmds.frameLayout('sliderFrame',collapsable=1,l=obj,bs="etchedOut")
cmds.rowColumnLayout('sliderPanel', nc = 2, columnWidth=[(2, 40)])
for attr in attributes:
fullName=(str(obj) + "." + str(attr))
cmds.attrFieldSliderGrp(cw=(1, 90),at=fullName,cat=(1, 'left', 10))
cmds.button(l='Sel',w=20, command = lambda *args: selectMe(fullName) )

def selectMe(who):
print 'selectMe:',who
cmds.select (who)
Can someone help?
Thanks.

NaughtyNathan
01-11-2011, 10:06 AM
there's already several posts on this topic EightBit, but the general idea seems to be that lambda cannot be used this way in a loop (like this at least). At least according to this excellent post about it from the pyMel guys:

http://www.luma-pictures.com/tools/pymel/docs/1.0/ui.html

:nathaN

inglobetechnologies
01-11-2011, 03:34 PM
Since the argument you pass to the 'selectMe' method is a string itself, you can try to define the button command as a string like this:

...
cmds.button(l='Sel',w=20, command = "selectMe('"+fullName+"')" )

def selectMe(*args):
print 'selectMe:',args[0]
cmds.select (args[0])

EightBit
01-11-2011, 04:18 PM
Nathan:
Thanks for the link. I see the problem, but how to do this in Python?
I found another post (http://forums.cgsociety.org/showthread.php?f=89&t=648707&highlight=args+loop) in which a callback class is created, but I don't know how to implement that in my code. I have a button in the UI to delete the sliders and then I have a separate function to recreate the slider panel based on the selection.

madone:
passing a string for the command, I get this error:
# NameError: name 'selectMe' is not defined #

def fillUDPanel():
global sliderContainer
sel=cmds.ls(sl=1)
if len(sel) == 0:
mel.error("You must have an object selected!")

for obj in sel:
attributes=cmds.listAttr(obj, ud=1)
if not attributes :
print obj,'doesn\'t have obj user-defined atttrs.'
continue
cmds.setParent('frameBegin')
sliderContainer = cmds.frameLayout('sliderFrame',collapsable=1,l=obj,bs="etchedOut")
cmds.rowColumnLayout('sliderPanel', nc = 2, columnWidth=[(2, 40)])
for attr in attributes:
fullName=(str(obj) + "." + str(attr))
cmds.attrFieldSliderGrp(cw=(1, 90),at=fullName,cat=(1, 'left', 10))
cmds.button(l='Sel',w=20, command = lambda *args: selectMe(fullName) )

inglobetechnologies
01-11-2011, 04:32 PM
it's strange 'cause in maya2011 it works smoothly
try to simply put the whole definition of 'selectMe' before the 'fillUDPanel' function. Something like this:

def selectMe(*args):
print 'selectMe:',args[0]
cmds.select (args[0])

def fillUDPanel():
...
cmds.button(l='Sel',w=20, command = "selectMe('"+fullName+"')" )




hope it works.

EightBit
01-11-2011, 05:27 PM
I'm getting the same error as b4.
Attached is the script if you'd like to take a look (its pretty simple).
If you select locator1 in the scene b4 running the script, it will load the panel.
Thanks

inglobetechnologies
01-11-2011, 06:50 PM
if you just copy-paste&run the script in the script editor it DOES work.
If you load it by using the Plug-in manager it DOES NOT.

I made the following steps:
- opened the sample model,
- selected the locator
- run the script in the script editor
it worked.

At this point I don't know what to say :shrug:

EightBit
01-11-2011, 07:13 PM
Getting different results in the SE vs in a script is discussed in the article linked in Nathans reply.
I posted this issue at Python In Maya (http://groups.google.com/group/python_inside_maya/browse_thread/thread/c381a9646557de7e#) and received this solution, which works:
Assign the value to an argument of the lambda
cmds.button(l='Sel',w=20, command = lambda x, y = fullName:selectMe(y) )

CGTalk Moderation
01-11-2011, 07:13 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.