Python Query Arbitrary Number of Checkboxes on Button Press


#1

I am working on a rigging script for Maya which uses a basic UI. One button creates a new window which varies depending on the objects the user has selected. For every object selected after the first one, the window will have a text field and two checkboxes, and underneath it all is a button that needs to query all of them when pressed.

def ssButtonPressed(sel):  
    #Check to see if the window already exists
    if cmds.window("ssWindow", exists = True):
        cmds.deleteUI("ssWindow")  
    ssWindow = cmds.window("ssWindow", title = "Space Switch setup", resizeToFitChildren = 1, mnb = False, mxb = False, sizeable=True)
    ssLayout = cmds.columnLayout("Layout test")
    ssGRP = sel[0]
    settingsList = [ [ ] ]
    
    #Create a text box and constraint options for every object selected after the space switch group
    for s in range(1, len(sel)):
        settings = []
        cmds.text(l=sel[s])
        settings.append(cmds.textField( it=sel[s]))
        settings.append(cmds.checkBox(l="Constrain translate", v=True))
        settings.append(cmds.checkBox(l="Constrian rotate", v=True))
        cmds.text(l="")
        settingsList.append(settings)
        
    #Space switch button
    cmds.button(l="Create Space Switch Attribute", annotation = "test",
    command = lambda *args: createssButtonPressed(settingsList))
    
    cmds.showWindow(ssWindow)

Since the number of checkboxes and text fields is dependent on the number of objects selected, I don’t know how to query all of them in the button command flag alone. I thought I could store each checkbox and text field in a list like you see above, and pass it into the function itself to query like this:

def createssButtonPressed(settingsList):
    settingsList2 = settingsList
    for obj in range(1, len(settingsList)):
        settingsList2[obj][0] = cmds.textField(settingsList[obj][0], q=True, tx=True)
        settingsList2[obj][1] = cmds.checkBox(settingsList[obj][1], q=True, v=True)
        settingsList2[obj][2] =cmds.checkBox(settingsList[obj][2], q=True, v=True)

If I were to select two spheres, pSphere1 and pSphere2, for example, and press the button, it creates a window with one text field and two checkboxes. Pressing the button there actually works fine if I only press it once, but if I press it a second time, Maya throws this error:

# Error: RuntimeError: file <maya console> line 1020: Object 'pSphere2' not found. # 

Line 1020 is where the text field gets queried.

If I print settingsList and settingsList2 before and after the query loop, I get this:

settingsList = [[], [u'ssWindow|Layout_test|textField13', u'ssWindow|Layout_test|checkBox26', u'ssWindow|Layout_test|checkBox27']]
settingsList2 = [[], [u'ssWindow|Layout_test|textField13', u'ssWindow|Layout_test|checkBox26', u'ssWindow|Layout_test|checkBox27']]
settingsList = [[], [u'pSphere1', True, True]]
settingsList2 = [[], [u'pSphere1', True, True]]

I don’t understand why the first settingsList gets overwritten with the queried values that are supposed to only be stored in settingsList2.

It might not be a huge deal, since the user ideally won’t need to press the button more than once if they got all of their settings correct the first time around. But I’m the kind of person who runs a function, watches everything go horribly wrong because I accidentally forgot or overlooked settings and options, and undos to try again. It would be very inconvenient to have to close and reopen the window every time.

I’m still kind of bumbling my way through both scripting in Python as well as wrapping my head around how UIs work, so any tips on a better way to go about writing a function like this or for better scripting practice in general would be very much appreciated.