user2153909
user2153909

Reputation: 11

Run Time Error using GUI in Maya with Pymel/Python

So I'm trying to make a GUI that allows the user the to build any of the specified polyShapes (chosen with check boxes) to whatever attributes they need (set in sliders). Also when each check box is selected it unselects the other boxes and greys-out certain attributes that the user doesn't need.

I'm struggling with the functions that define what happens when each of the check boxes is selected. When the checkbox is selected, attributes set and the create button is pressed the process works just fine (with the outcome I expect) but I get the following error, with all but the last check box:

RuntimeError: Object 'window1|formLayout46|checkBox3' not found. #

I have been told that this is an error due to the functions running off of old/previous versions of the window, and that passing the sliders etc as arguments into the functions will fix the error. However, this does not solve the problem, and of course I can't pass check boxes as argument before they are created' as demonstrated in the code below. It also does not explain why the last check box (checkBoxCylinder) works just fine - I am assuming this works fine because everything has already been made before it.

Any suggestions/explanations on this matter will be greatly appreciated as I now feel like I'm going around in circles. Apologies for the long code below, I couldn't use an extract as it all links together!!

import pymel.core as pm

class MakeLightDome(object):

def __init__(self):
    sel = []

def checkSelection(self):
    sel = pm.ls(selection = True)
    length = len(sel)

#Check Selection    
    if length == 0:
        print "Please create a PolySphere."

        def show():
            global win
            try:
                win.delete()
            except:
                pass
            win = pm.window(title = "Dome Generator")

            mainLayout = pm.verticalLayout()
            mainLayout.setHeight(400)


            def buttonPressed(*args):
                #Create Sphere
                if checkBoxSphere.getValue():
                    radiusSet = rSlider.getValue()
                    xSubDivs = xSubDSlider.getValue()
                    ySubDivs = ySubDSlider.getValue()
                    pm.polySphere(r = radiusSet, sx = xSubDivs, sy = ySubDivs)
                #Move on to create lights        
                    win.delete()

                if checkBoxCube.getValue():
                #CreateCube
                    xDime = xSlider.getValue()
                    yDime = ySlider.getValue()
                    zDime = zSlider.getValue()
                    xSubDivs = xSubDSlider.getValue()
                    ySubDivs = ySubDSlider.getValue()
                    zSubDivs = zSubDSlider.getValue()
                    pm.polyCube(w = xDime, h = yDime, d = zDime, sx = xSubDivs, sy = ySubDivs, sz = zSubDivs)
                #Move on to create lights        
                    win.delete()

                if checkBoxCone.getValue():
                #Create Cone
                    yDime = ySlider.getValue()
                    radiusSet = rSlider.getValue()
                    xSubDivs = xSubDSlider.getValue()
                    ySubDivs = ySubDSlider.getValue()
                    zSubDivs = zSubDSlider.getValue()
                    pm.polyCone(h = yDime, r = radiusSet, sx = xSubDivs, sy = ySubDivs, sz = zSubDivs)
                #Move on to create lights        

                    win.delete()

                if checkBoxCylinder.getValue():
                #Create Cylinder 
                    yDime = ySlider.getValue()
                    radiusSet = rSlider.getValue()
                    xSubDivs = xSubDSlider.getValue()
                    ySubDivs = ySubDSlider.getValue()
                    zSubDivs = zSubDSlider.getValue()
                    pm.polyCylinder(h = yDime, r = radiusSet, sx = xSubDivs, sy = ySubDivs, sz = zSubDivs)
                #Move on to create lights        
                    win.delete()

            def sphereBoxChecked(*args):
                xSlider = args[0]
                ySlider = args[1]
                zSlider = args[2]
                rSlider = args[3]
                xSubDSlider = args[4]
                ySubDSlider = args[5]
                zSubDSlider = args[6]
                checkBoxCube = args[7]
                checkBoxCone = args[8]
                checkBoxCylinder = args[9]
            #Checkbox off
                checkBoxCube.setValue(False)
                checkBoxCone.setValue(False)
                checkBoxCylinder.setValue(False)
             #Slider enable
                xSlider.setValue(en = False)
                ySlider.setValue(en = False)
                zSlider.setValue(en = False)
                rSlider.setValue(5, en = True)
                xSubDSlider.setValue(10, en = True)
                ySubDSlider.setValue(10, en = True)
                zSubDSlider.setValue(en = False)


            def cubeBoxChecked(*args):
                xSlider = args[0]
                ySlider = args[1]
                zSlider = args[2]
                rSlider = args[3]
                xSubDSlider = args[4]
                ySubDSlider = args[5]
                zSubDSlider = args[6]
                checkBoxSphere = args[7]
                checkBoxCone = args[8]
                checkBoxCylinder = args[9]
            #Checkbox off
                checkBoxSphere.setValue(False)
                checkBoxCone.setValue(False)
                checkBoxCylinder.setValue(False)
            #Slider enable
                xSlider.setValue(10, en = True)
                ySlider.setValue(10, en = True)
                zSlider.setValue(10, en = True)
                rSlider.setValue(en = False)
                xSubDSlider.setValue(5, en = True)
                ySubDSlider.setValue(5, en = True)
                zSubDSlider.setValue(5, en = True)

            def coneBoxChecked(*args):
                xSlider = args[0]
                ySlider = args[1]
                zSlider = args[2]
                rSlider = args[3]
                xSubDSlider = args[4]
                ySubDSlider = args[5]
                zSubDSlider = args[6]
                checkBoxSphere = args[7]
                checkBoxCube = args[8]
                checkBoxCylinder = args[9]
            #Checkbox off
                checkBoxSphere.setValue(False)
                checkBoxCube.setValue(False)
                checkBoxCylinder.setValue(False)
            #Slider enable
                xSlider.setValue(en = False)
                ySlider.setValue(10, en = True)
                zSlider.setValue(en = False)
                rSlider.setValue(5, en = True)
                xSubDSlider.setValue(15, en = True)
                ySubDSlider.setValue(10, en = True)
                zSubDSlider.setValue(5, en = True)

            def cylinderBoxChecked(*args):
            #Checkbox off
                checkBoxSphere.setValue(False)
                checkBoxCube.setValue(False)
                checkBoxCone.setValue(False)
            #Slider enable
                xSlider.setValue(en = False)
                ySlider.setValue(15, en = True)
                zSlider.setValue(en = False)
                rSlider.setValue(5, en = True)
                xSubDSlider.setValue(15, en = True)
                ySubDSlider.setValue(5, en = True)
                zSubDSlider.setValue(5, en = True)

        #Slider settings
            #Dimensions
            xSlider = pm.floatSliderGrp(label = "x Dimension", field = True, parent = mainLayout, en = False)
            xSlider.setValue(10)
            ySlider = pm.floatSliderGrp(label = "y Dimension", field = True, parent = mainLayout, en = False)
            ySlider.setValue(10)
            zSlider = pm.floatSliderGrp(label = "z Dimension", field = True, parent = mainLayout, en = False)
            zSlider.setValue(10)
            rSlider = pm.floatSliderGrp(label = "Radius", field = True, parent = mainLayout, en = False)
            rSlider.setValue(10)
            #SubDivisions
            xSubDSlider = pm.intSliderGrp(label = "x SubDivs",field = True, parent = mainLayout, en = False)
            xSubDSlider.setValue(10)
            ySubDSlider = pm.intSliderGrp(label = "y SubDivs", field = True, parent = mainLayout, en = False)
            ySubDSlider.setValue(10)
            zSubDSlider = pm.intSliderGrp(label = "z SubDivs", field = True, parent = mainLayout, en = False)
            zSubDSlider.setValue(10)

        #Check Box Settings
            checkBoxSphere = pm.checkBox(label = "Sphere", value = False, parent = mainLayout, onc = pm.Callback(sphereBoxChecked, xSlider, ySlider, zSlider, rSlider, xSubDSlider, ySubDSlider, zSubDSlider, checkBoxCube, checkBoxCone, checkBoxCylinder))
            checkBoxCube = pm.checkBox(label = "Cube", value = False, parent = mainLayout, onc = pm.Callback(cubeBoxChecked, xSlider, ySlider, zSlider, rSlider, xSubDSlider, ySubDSlider, zSubDSlider, checkBoxSphere, checkBoxCone, checkBoxCylinder))
            checkBoxCone = pm.checkBox(label = "Cone", value = False, parent = mainLayout, onc = pm.Callback(coneBoxChecked, xSlider, ySlider, zSlider, rSlider, xSubDSlider, ySubDSlider, zSubDSlider, checkBoxSphere, checkBoxCube, checkBoxCylinder))
            checkBoxCylinder = pm.checkBox(label = "Cylinder", value = False, parent = mainLayout, onc = pm.Callback(cylinderBoxChecked))


            btn = pm.button(label = "Create", parent = mainLayout, command = pm.Callback(buttonPressed))
            mainLayout.redistribute()

            win.show()
        show()
dome = MakeLightDome()
dome.checkSelection()

Upvotes: 1

Views: 1120

Answers (1)

theodox
theodox

Reputation: 12208

You probably don't want to use as a global for this, it complicates your state management. The generally 'right' way to do this (air quotes on purpose) is to wrap the GUI in a class and store all your state in the class so it's easy to know that all of it connects the same state data to the same widgets. Besides keeping the code much tidier it also makes it possible to have multiple copies of the same dialog open (say, one per object if you needed that sort of thing).

Here's an extremely simple example. Since all of the widgets (at least, all the ones you care about) are included in the dialog's 'self', it's trivial to get the info you need when you respond to a button click

import pymel.core as pm

class SliderDialog(object):

     def __init__(self):
        self.SomeSpecialData = "Hello world"
        self.Window = pm.window(width = 300)
        with pm.columnLayout():
           self.XSlider = pm.floatSliderGrp(label  = 'x', field = True)
           self.YSlider = pm.floatSliderGrp(label  = 'y', field = True)
           self.ZSlider = pm.floatSliderGrp(label  = 'z', field = True)
           with pm.rowLayout(nc= 2):
               self.Cancel = pm.button("cancel", width = 150, command = self.cancel_button)
               self.Go = pm.button("go", width = 150, c=self.go_button)
     def show(self):
         self.Window.show()

     def go_button(self, *_):
         # your actual work goes here
         print "Special Data = ", self.SomeSpecialData 
         x, y, z = self.XSlider.getValue(), self.YSlider.getValue(),  self.ZSlider.getValue()          

         print "do something with XYZ (%i, %i, %i)" % (x, y, z)

     def cancel_button(self, *_):
         print "cancelling"
         pm.deleteUI(self.Window)

SliderDialog().show()

Here is a detailed reference on hooking python functions to maya GUI callbacks.

Upvotes: 1

Related Questions