2013-03-14 48 views
0

所以我試圖創建一個GUI,允許用戶使用任何屬性來創建指定的polyShapes(用複選框選擇)(在滑塊中設置)。此外,當選中每個複選框時,將取消選擇其他框,並灰顯用戶不需要的某些屬性。運行時錯誤在Pyam/Python中使用Maya中的GUI

我正在努力定義每個複選框被選中時會發生什麼的函數。如果選中該複選框,屬性設置和創建按鈕被按下的過程中工作得很好(與我期望的結果),但我得到以下錯誤,與所有,但最後一個複選框:

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

我有被告知這是一個錯誤,這是由於舊窗口/以前版本的功能失效,並且將滑塊等作爲參數傳遞給函數將修復錯誤。然而,這並不能解決問題,當然我不能將複選框作爲參數傳遞給它們,正如下面的代碼所演示的那樣。它也不能解釋爲什麼最後一個複選框(checkBoxCylinder)工作得很好 - 我假設這工作正常,因爲所有東西都已經在它之前完成了。

任何有關此事的建議/解釋將不勝感激,因爲我現在感覺自己像是在繞圈子一樣。對於下面的長代碼抱歉,我無法使用提取,因爲它們都鏈接在一起!

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() 

回答

0

您可能不希望將其作爲全局使用,這會使您的狀態管理複雜化。通常「正確」的方法是將GUI包裝在類中,並將所有狀態存儲在類中,以便知道它將所有狀態數據連接到相同的小部件。除了保持代碼更整潔以外,還可以打開同一個對話框的多個副本(比如,如果你需要這樣的話,每個對象一個)。

這是一個非常簡單的例子。由於所有的部件(至少,所有那些你在乎)都包含在該對話框的「自我」,是微不足道的獲得,當你到一個按鈕迴應你所需要的信息請點擊

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.