[PYTHON] Light UI problems

Hi everyone,

Im currently trying to build a light ui to control the renderman lights in my scene (I know renderman has one but I want a bit more control than what it offers) however Im having a little trouble getting the light attributes in the UI to control the actual light attributes (I hope that makes sense). So far Ive gotten my buttons to work but as the UI creates attributes per light I cant name the text field grps, checkBoxes, etc (i.e. mc.textFieldGrp(“Lights1”), If i name it I get an error saying that the name is not unique. Is there a better way of doing this? Or is there a way for maya to create a new name based on every light, is that even possible. Any help would be most appreciated.

Here is my code so far:

import maya.cmds as mc
   
#prevent the duplication of window
if mc.window("lightSel_win", ex= True):
    mc.deleteUI("lightSel_win", window=True)
    
    
#Create a Window
mc.window("lightSel_win", t="Light Lister", s= False, width= 1500 )

#Give the window an adjustable column layout
mc.columnLayout ("c_layout", columnAttach=('both', 5), adjustableColumn=True)

########### Geo ButtonLayout ################################################

mc.rowColumnLayout ("LayoutColFrame", numberOfColumns= 1, p= "c_layout")

#Frame Layout for Geobutton
mc.frameLayout ("GeoBFrame", font= "boldLabelFont", label= "Pxr Standard Area Light(S)", collapsable= True, borderVisible= False, p= "LayoutColFrame")

#Column Layout for Geobutton
mc.columnLayout ("GeoButtonLayout", p= "GeoBFrame", adjustableColumn= False)

#Button for Geobutton
mc.button("b_AddGeoLights", label="Add Geometric Light(S)", h= 30, c= "AddGeoLights()", p="GeoButtonLayout", w= 300, rs= False)

#Column Layout for Title
mc.rowColumnLayout ("Area_lights", numberOfColumns= 1, p= "GeoBFrame")
 
#Text For Title
mc.text("Renderman Area Light(S)", p= "Area_lights", font= "plainLabelFont") 

#Col Area_lights_Settings_Cont
mc.rowColumnLayout ("Area_lights_Settings_Cont", numberOfRows= 1, p= "GeoBFrame")

#Col Title Light Name
mc.rowColumnLayout ("T_LightNameCol", numberOfColumns=1, p= "Area_lights_Settings_Cont", columnSpacing= (5,5), cal= (1,"left"))

#Text Title Light Name
mc.text("Light Name", p= "T_LightNameCol") 

#LightName Setting Col
mc.rowColumnLayout ("LightName_Col", numberOfColumns= 1, p= "Area_lights_Settings_Cont", columnSpacing= (5,5), cal= (1,"left"))

#Col Title Exp 
mc.rowColumnLayout ("T_ExpCol", numberOfColumns=1, p= "Area_lights_Settings_Cont")

#Text Title Exp 
mc.text("Exposure", p= "T_ExpCol")

#Exposure Setting Col
mc.rowColumnLayout ("Exp_Col", numberOfColumns= 1, p= "Area_lights_Settings_Cont")

#Col Title Shading Rate
mc.rowColumnLayout ("T_ShadingRateCol", numberOfColumns=1, p= "Area_lights_Settings_Cont")

#Text Title Shading Rate
mc.text("Shading Rate", p= "T_ShadingRateCol")

#Shading Rate Settings Col
mc.rowColumnLayout ("Shading_Col", numberOfColumns= 1, p= "Area_lights_Settings_Cont")

#Col Title Shape
mc.rowColumnLayout ("T_ShapeCol", numberOfColumns=1, p= "Area_lights_Settings_Cont")

#Text Title Shape
mc.text("Shape", p= "T_ShapeCol")

#Shape Setting Col
mc.rowColumnLayout ("LShape_Col", numberOfColumns= 1, p= "Area_lights_Settings_Cont")

#Col Title Color
mc.rowColumnLayout ("T_ColorCol", numberOfColumns=1, p= "Area_lights_Settings_Cont")

#Text Title Color
mc.text("Color", p= "T_ColorCol")

#Color Setting Col
mc.rowColumnLayout ("Color_Col", numberOfColumns= 1, p= "Area_lights_Settings_Cont")

#Col Title Visibility
mc.rowColumnLayout ("T_VisibilityCol", numberOfColumns=1, p= "Area_lights_Settings_Cont")

#Text Title Visibility
mc.text("Visibility", p= "T_VisibilityCol")

#Visibility Setting Col
mc.rowColumnLayout ("Visibility_Col", numberOfColumns= 1, p= "Area_lights_Settings_Cont")

############################################################

#Add instructions for the first window

mc.rowColumnLayout ("EnviroButtonLayout", numberOfColumns= 1, p= "c_layout")

mc.button("b_AddEnviroLights", label="Add Enviroment Light(S)", h= 30, c= "AddEnviroLights()", p="EnviroButtonLayout", w= 300)

#Add inst for second half of the window
mc.rowColumnLayout ("Enviro_lights", numberOfColumns= 1, p= "c_layout")

mc.text("Renderman Enviro Light", p= "Enviro_lights")


mc.rowColumnLayout ("OtherButtonLayout", numberOfRows= 1, p= "c_layout")

"""
#Create a Text Field Group to allow users to set the name, amount and Temperature etc...
mc.textFieldGrp("RendermanlightName", label= "Light Name:")
mc.textFieldGrp("LightExposure", label= "Exp:")
mc.textFieldGrp("RendermanShading", label= "Shading Rate:")
mc.textFieldGrp("Reso", label= "Map Resolution:")
mc.textFieldGrp("LightTemp", label= "Color:")
mc.textFieldGrp("Img", label= "Env Map:")
"""

# Create 2 buttons and parent them to the layout
mc.button("b_Render", label="Render!", h= 30, c= "Render()", p="OtherButtonLayout", w= 300)
mc.button("b_RenderSelLights", label="Render Selected Lights", h= 30, c= "RenderSelLight()", p="OtherButtonLayout", w= 300)
mc.button("b_CLight", label="Create Light", h= 30, c= "Clight()", p="OtherButtonLayout", w= 300)

#Show the Window
mc.showWindow("lightSel_win")

def Render():
    
    #Starts Render
    mel.eval('execRmanMenuItem("Render")')


#####This is where the lights are added to the UI####
    
## Defining Add geo Lights Button
def AddGeoLights():
                          
    sel = cmds.ls(sl = True, dag = True, shapes = True)
    selAllLights = []
    
    #For Loop - "for every light selected in (sel), run the following commands"
    for allLights in sel:
        
        if cmds.nodeType(allLights) == "PxrStdEnvMapLight" or cmds.nodeType(allLights) == "PxrStdAreaLight" or cmds.nodeType(allLights) == "PxrStdEnvDayLight":
            selAllLights.append(allLights)
            
        else:
            pass
            
    if not selAllLights:
            cmds.confirmDialog(m = "No lights selected!", button = "Ok")
            raise ValueError("No lights selected") 
        
    for allLights in sel:
                
        #Create a Text Field Group to allow users to set the name, amount and Temperature etc...
        mc.textFieldGrp(label= "Light Name:", p= "T_LightNameCol", w= 250, changeCommand= "Light()")
        mc.textFieldGrp(label= "Exp:", p= "T_ExpCol", w= 200, changeCommand= "Exp()")
        mc.textFieldGrp(label= "Shading Rate:", p= "T_ShadingRateCol", w= 200, changeCommand= "Shading()")
        mc.optionMenu(label= "Light Shape:", p= "T_ShapeCol", w= 120, changeCommand= "Shape()")
        mc.menuItem(label="rect")
        mc.menuItem(label="disk")
        mc.menuItem(label="sphere")
        mc.menuItem(label="cylinder")
        mc.menuItem(label="distant")
        mc.menuItem(label="spot")
        mc.colorIndexSliderGrp(label='Select Color', min=0, max=20, value=10, p= "T_ColorCol", dragCommand= "colSli()")
        mc.checkBox (label= "Primary Visibility", p= "T_VisibilityCol")
    
###########################################################    
        
def Clight():
    
    mc.shadingNode('PxrStdAreaLight', asLight= True)
          
def RenderSelLight():
    
    sel = cmds.ls(sl = True, dag = True, shapes = True)
    selAllLights = []

    for allLights in sel:
        
        if cmds.nodeType(allLights) == "PxrStdEnvMapLight" or cmds.nodeType(allLights) == "PxrStdAreaLight" or cmds.nodeType(allLights) == "PxrStdEnvDayLight":
            selAllLights.append(allLights)
            
        else:
            pass
            
    if not selAllLights:
            cmds.confirmDialog(m = "No lights selected!", button = "Ok")
            raise ValueError("No lights selected")
    else:
        lightSelSet = cmds.sets()
        cmds.connectAttr(lightSelSet + ".message", "rmanFinalGlobals.rman__torattr___lightcrew", force = True)
        try:
            mel.eval('execRmanMenuItem("Render")')
            cmds.delete(lightSelSet)
        except RuntimeError:
            print "Error during render"
            cmds.delete(lightSelSet)

Heres a picture of the UI


Take a look at the documentation for the following ui commands:

attrColorSliderGrp
attrControlGrp
attrFieldGrp
attrFieldSliderGrp
attrNavigationControlGrp

These can be connected directly to an attribute.

I know you didn’t ask for a code style critique, but, it was difficult to follow your script. Consider how you are documenting and structuring your code. I would suggest reading PEP8 and maybe the google python style guide. Documenting for loops and making line breaks out of comments is strange. Use blank lines to group code logically. For example, if you’re adding 4 controls to a layout, don’t place a blank line between each of the controls they all belong in the same place, just as they do in your UI. Write code that’s clear to you without comments, and it should be clear to anyone else who is reading it. Think of function, class, and reference names as self-documenting. If these names are explicit and clear, your code will be as well.

#Edit

One more thing, I might consider using grid layouts instead of formlayouts as they are far easier to manage. Check out this old post.