Re: python - to create dynamic buttons with commands

1,071 views
Skip to first unread message

Don Campbell IV

unread,
Nov 4, 2012, 5:49:01 PM11/4/12
to python_in...@googlegroups.com
Sorry dummy scene not included.  If you make a maya file with the quick select sets and a sphere for each would would work. - Thanks - Don


Justin Israel

unread,
Nov 4, 2012, 10:58:53 PM11/4/12
to python_in...@googlegroups.com
Whenever you are creating dynamic objects in a loop, it usually is best to save them into a data structure, such as a dictionary. In this case, you are replacing self.btnA each time with a new button. The result is when your callback fires, you are always operating on that same last button in the loop.

You could pass any number of information to the callback using partial, but in my example I will just pass the button name. The callback will just take that button name, and query the label, and then look up the quick select set on the instance.

Also, I found what seemed like a bit of a bug when trying to select the set and then immediately call the Key All operation on the channelBox. It seemed like for the first selection you do, the channelBox doesn't see the selection in time and does nothing. Then with something selected, the next button will work. So I just replaced the whole thing within keying it manually.


import maya.cmds as cmds
from functools import partial

    
def myfunc2(inst=None, thing=None, arg=None):
    # thing will be the button name
    label = cmds.button(thing, query=True, label=True)
    # look up the selection set from the button name
    quickSel = inst.buttons[thing]
    cmds.select(quickSel, replace=True)
    # used a manual KEY ALL because I was finding a
    # bug with the selection of the first button and 
    # the channelBox not seeing any items in time
    for node in cmds.ls(sl=True, l=True):
        for attr in cmds.listAttr(node, r=True, w=True, k=True, v=True):
            cmds.setKeyframe('%s.%s' % (node, attr))


class ui():
    def __init__(self, winName="winTheWindow"):
        self.winTitle = "The Window"
        self.winName = winName
        # save our dynamic buttons here with any meta data we want
        self.buttons = {}
 
    def create(self,setList):
        if cmds.window(self.winName, exists=True):
            cmds.deleteUI(self.winName)

        cmds.window(self.winName, title=self.winTitle)
        self.mainCol = cmds.columnLayout( adjustableColumn=True )
        
        for i in setList.split(","):
            name = "%s Key ALL" % i
            button = cmds.button(label=name)
            # pass the button name as the "thing"
            cmds.button(button, e=True, c=partial(myfunc2, self, button)) 
            # save our button in a dict, with the select set as the value
            self.buttons[button] = i  
            
        cmds.showWindow( self.winName )
        cmds.window(self.winName, edit=True, widthHeight=[250,75])




On Nov 4, 2012, at 1:59 PM, Don Campbell IV wrote:

Hi everyone,

I am definitely in over my head here.  The original goal was to dynamically create a window of buttons that is createdh from the quick selects menu. Each button would select the given selection set and key all.  I have borrowed some code from a guy who is smarter than I that has a lot of cool button options.  I have included a dummy scene that has 3 pSperes and should have each sphere in a quick select set named ballSet1,ballSet2 and ballSet3.  I would love any suggestions.

Thanks.

Don

Original code. THANKS RYAN!
http://www.rtrowbridge.com/blog/2010/02/maya-python-ui-example/

Here is my attempts to loop through list and dynamically create buttons. I want to dynamically create the code that goes along with the buttons as well

[/code]

import maya
.cmds as cmds
from functools import partial

def myfunc
(inst=Nonething=Nonearg=None):
    print 
'arg: 'arg
    
print 'inst: 'inst
    
print 'thing: 'thing
    data 
cmds.button(inst.btnAquery=Truelabel=True)
    print 
data
    
## This is my addition. 
def myfunc2(inst=Nonething=Nonearg=None):
    print 
'arg: 'arg
    
print 'inst: 'inst
    
print 'thing: 'thing
    data 
cmds.button(inst.btnAquery=Truelabel=True)
    print 
data
    
## what I want to do here is via a loop (IE ballSet1 then ballSet2 ect)
    ## is to not just get the buttons but with code select the corrisponding selection set. 
    ## and then use the KEY ALL command. 
    
    


class ui():
    
def __init__(selfwinName="winTheWindow"):
        
self.winTitle "The Window"
        
self.winName winName
 
    def create
(self,setList):
        if 
cmds.window(self.winNameexists=True):
            
cmds.deleteUI(self.winName)

        
cmds.window(self.winNametitle=self.winTitle)
        
self.mainCol cmds.columnLayoutadjustableColumn=True )
        
        
#this is my addition to loop through and get the buttons named and created dynamically.
        
for i in setList.split(","):
            print 
i
            self
.btnA cmds.buttonlabel" Key ALL"c=partial(myfunc2selfi) )    #see myfunc2 above for my issues.
            #self.btnA = cmds.button( label= i + " Key ALL", c=myfunc2(i))
            
        # This is the original dummy code from the original author. 
        #self.btnA = cmds.button( label='Press Me - External Func', c=partial(myfunc, self, 'say...') )
        #self.btnB = cmds.button( label='Press Me - Internal Func', c=partial(self.a, 'something...') )
        #self.btnC = cmds.button( label='Press Me - Internal Func No Args', c=self.b)
        
cmds.showWindowself.winName )
        
cmds.window(self.winNameedit=TruewidthHeight=[250,75])

    
def a(selfmyarg=Nonearg=None):
        print 
'myarg: 'myarg

    def b
(selfarg=None):
        print 
'buttons require an argument'
        
print 'the argument passed in will always be the last argument'

# I already the code to get the sets to save space I just created a list.
setList "ballSet1,ballSet2,ballSet3"

# create the window
inst ui()
inst.create(setList)

[code]

--
view archives: http://groups.google.com/group/python_inside_maya
change your subscription settings: http://groups.google.com/group/python_inside_maya/subscribe

Don Campbell IV

unread,
Nov 6, 2012, 11:41:31 AM11/6/12
to python_in...@googlegroups.com
Hi Justin,

Big thanks and so quick!  Ok here is my code. I am playing around with a rig from this talented rigger and I want have easier access to the quick selection sets he created. Thats what started me down this road.  He had all sets prefixed with qss.  So finding them was pretty easy. 


Here is the updated code that gets all the prefixed quick selects from with in maya. 



In the future I would want to make the prefix user definable and or just simply list the user created quick select sets that only selects the sets( no keying or other actions) 

Thanks a bunch Justin!

Don


Justin Israel

unread,
Nov 6, 2012, 6:57:16 PM11/6/12
to python_in...@googlegroups.com, python_in...@googlegroups.com
Happy to help!

Couple things you might want to correct in your latest pastebin. 

Your create method takes a setList variable but you are actually referencing that global list you make at the bottom and ignoring what you pass in:

    for i in setnames:

Should be:

    for i in setList:

The other two things are super minor, at the bottom. The split() isn't doing anything since it would require you assigning the results to something. And you probably don't need to split on a comma anyways anymore. Also, try to avoid using variable that shadow the builtin objects. "set" is a built in container type. 

Don Campbell IV

unread,
Nov 7, 2012, 11:11:53 AM11/7/12
to python_in...@googlegroups.com

Here is a the code cleaned up.  Thanks again!  Don.

Reply all
Reply to author
Forward
0 new messages