Reputation: 11
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
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