Python - Running a function on interactively created buttons


#1

Hi guys, Say I have a small script that upon pressing a button, it lists all ncloth nodes in my scene and displays them as buttons somewhere on my UI, how can I do that upon pressing this new buttons, it runs a function that only affects the nCloth node represented by the pressed button?

So far I have something like this, but I’m missing the functionality to (at the moment) just print the name of the pressed button. Any help would be gladly appreciated :slight_smile:

import maya.cmds as cmds
  
  def printButtonName (buttonName):
  	print ('You pressed button named: ' + buttonName)
  
  def listClothObjs(*args):
  	theExistingButtons = cmds.scrollLayout ('nClothScrollList', query=True, childArray=True)			
  	if theExistingButtons > 0:			
  		for theButton in theExistingButtons:			
  			cmds.deleteUI (theButton)			
  
  	theNodes = cmds.ls (type='nCloth')
  	for node in theNodes:
  		cmds.setParent ('nClothScrollList')
  		cmds.button ((node + '_button'), backgroundColor=(.2,.2,.2),width=120, command= printButtonName)
  
  if (cmds.window('theWin', exists=True)):									
  	cmds.deleteUI('theWin')
  
  cmds.window('theWin', title="The Window")
  cmds.columnLayout()
  cmds.button ('listnCloth', command= listClothObjs)
  cmds.scrollLayout ('nClothScrollList', w=125 , h=150, backgroundColor=(0,0,0) )
  cmds.setParent ('..')
  cmds.showWindow ('theWin')

#2

You want to give the printButtonName the button name as argument. That can be done by lambda functions or partial functions. I personally do not like lambdas because they are not easy to read. I perfer callbacks or partial functions:

import pymel.core as pm

def printButtonName(name):
	print name
...
cmds.button(label="Button1", c=pm.Callback(printButtonName, "Button1"))

or

import functools
 
 def printButtonName(name):
 	print name
 ...
 cmds.button(label="Button1", c=functools.partial(printButtonName, "Button1"))