Maya Python: cmds.button () с передаваемыми переменными UI и вызовом функции?

Прежде всего, это, кажется, отличное место, чтобы больше узнать о программировании. Я написал сценарий майя python, где работают обе функции, но у меня возникли проблемы с тем, что кнопка UI вызывает функцию superExtrude (). Первая функция выполняет геометрические манипуляции сетки, а вторая – пользовательский интерфейс для пользовательских входов:

import maya.cmds as cmds def superExtrude(extrScale, extrDist): """Loops through a list of selected meshes and extrudes all of the mesh faces to produce a polygon frame, based on existing mesh tesselations""" myObjectLt = cmds.ls(selection=True) for i in range(len(myObjectLt)): numFaces = cmds.polyEvaluate(face=True) item = myObjectLt[i] + ".f[:]" cmds.select(clear=True) cmds.select(item, replace=True) #extrude by scale cmds.polyExtrudeFacet(constructionHistory=True, keepFacesTogether=False, localScaleX=extrScale, localScaleY=extrScale, localScaleZ=extrScale) selFaces = cmds.ls(selection=True) cmds.delete(selFaces) #extrude by height cmds.select(item, replace=True) cmds.polyExtrudeFacet(constructionHistory=True, keepFacesTogether=True, localTranslateZ=extrDist) def extrWindow(): """Creates the user interface UI for the user input of the extrusion scale and height""" windowID = "superExtrWindow" if cmds.window(windowID, exists=True): cmds.deleteUI(windowID) cmds.window(windowID, title="SuperExtrude", sizeable=False, resizeToFitChildren=True) cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,120),(2,120)], columnOffset=[1,"right",3]) cmds.text(label="Extrusion Scale:") extrScaleVal = cmds.floatField(text=0.9) cmds.text(label="Extrusion Height:") extrDistVal = cmds.floatField(text=-0.3) cmds.separator(height=10, style="none") cmds.separator(height=10, style="none") cmds.separator(height=10, style="none") cmds.button(label="Apply", command=superExtrude(extrScaleVal, extrDistVal)) cmds.showWindow() extrWindow() 

Я довольно новичок в написании сценариев python и майя, поэтому любая помощь будет очень признательна. 🙂

  • Разница между re.search () и re.findall ()
  • Как заставить XPath выбрать несколько элементов таблицы с одинаковыми атрибутами идентификатора?
  • Как вернуть значение из Python как JSON?
  • Как проверить, находятся ли все элементы в кортеже или списке в другом?
  • Pandas timeseries plot задает основные и второстепенные тики и метки x-axis
  • Чтение нескольких CSV-файлов в Python Pandas Dataframe
  • В чем разница между «pylab» и «matplotlib.pyplot»?
  • Pytest - привязка к функциональному уровню
  • 4 Solutions collect form web for “Maya Python: cmds.button () с передаваемыми переменными UI и вызовом функции?”

    Я не уверен, что это ответ, который вы хотите, но что вам нужно знать о майских «командах»:

    • Если вы хотите поместить функцию в вызов кнопки, вам нужно передать имя функции без каких-либо аргументов (например: command = myFunction) (избавиться от конечных скобок «()»)

    • в вашей функции вам нужно добавить «* args», потому что кнопка maya всегда передает аргумент (я думаю, что это «False») (например: def myFunction (customArg1, customArg2, * args))

    • Если вы хотите передать аргументы в сигнале кнопки, вам нужно использовать частичную функцию из модуля functools (из частичного импорта из functools) и использовать его следующим образом: cmds.button (command = partial (myFunction, arg1, arg2, kwarg1 = value1, kwarg2 = value2))

    Еще одна вещь, о pymel и cmds … это, вероятно, бесконечная история, но pymel не всемогущ … Когда вам приходится иметь дело с большим количеством информации (например, получить список вершин на сетке), pymel может быть чем-то как на 40 раз медленнее, чем простые майские команды. У него есть свои плюсы и минусы … Если вы только что начали с python, я бы не рекомендовал сейчас попасть в pymel. Ознакомьтесь с синтаксисом и командами, и когда вы в порядке, переключитесь на pymel (что очень полезно, когда вы имеете дело с созданием объектов)

    Надеюсь, это помогло, Cheers

    Редактировать :

    На основе вашего первого сообщения, что вам нужно изменить в коде, чтобы заставить его работать:

     import maya.cmds as cmds from functools import partial #You need to add the *args at the end of your function def superExtrude(extrScaleField, extrDistField, *args): """Loops through a list of selected meshes and extrudes all of the mesh faces to produce a polygon frame, based on existing mesh tesselations""" myObjectLt = cmds.ls(selection=True) #In the function, we are passing the floatFields, not their values. #So if we want to query the value before running the script, we need to #use the floatField cmds with the "query" flag extrScale = cmds.floatField(extrScaleField, q=1, v=1) extrDist = cmds.floatField(extrDistField, q=1, v=1) for i in range(len(myObjectLt)): numFaces = cmds.polyEvaluate(face=True) item = myObjectLt[i] + ".f[:]" cmds.select(clear=True) cmds.select(item, replace=True) #extrude by scale cmds.polyExtrudeFacet(constructionHistory=True, keepFacesTogether=False, localScaleX=extrScale, localScaleY=extrScale, localScaleZ=extrScale) selFaces = cmds.ls(selection=True) cmds.delete(selFaces) #extrude by height cmds.select(item, replace=True) cmds.polyExtrudeFacet(constructionHistory=True, keepFacesTogether=True, localTranslateZ=extrDist) def extrWindow(): """Creates the user interface UI for the user input of the extrusion scale and height""" windowID = "superExtrWindow" if cmds.window(windowID, exists=True): cmds.deleteUI(windowID) cmds.window(windowID, title="SuperExtrude", sizeable=False, resizeToFitChildren=True) cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,120),(2,120)], columnOffset=[1,"right",3]) cmds.text(label="Extrusion Scale:") # There were an error here, replace 'text' with 'value' # to give your floatField a default value on its creation extrScaleVal = cmds.floatField(value=0.9) cmds.text(label="Extrusion Height:") extrDistVal = cmds.floatField(value=-0.3) cmds.separator(height=10, style="none") cmds.separator(height=10, style="none") cmds.separator(height=10, style="none") # As said above, use the partial function to pass your arguments in the function # Here, the arguments are the floatFields names, so we can then query their value # everytime we will press the button. cmds.button(label="Apply", command=partial(superExtrude,extrScaleVal, extrDistVal)) cmds.showWindow(windowID) extrWindow() 
     cmds.button(label="Apply", command=superExtrude(extrScaleVal, extrDistVal)) 

    Эта строка вызывает superExtrude и присваивает ее возвращаемое значение command . Поскольку superExtrude ничего не возвращает, кнопка эффективно имеет комбинацию None .

    Возможно, вы хотели, чтобы superExtrude вызывался при нажатии кнопки, и в этом случае вы должны обернуть ее в лямбда, чтобы она не superExtrude немедленно:

     cmds.button(label="Apply", command=lambda *args: superExtrude(extrScaleVal, extrDistVal)) 

    St4rb0y

    Во-первых, ваши вызовы floatField (строки 33, 35) используют недопустимый флаг «текст». Вероятно, вы хотите использовать «значение», поэтому измените обе строки.

     extrScaleVal = cmds.floatField(v=0.9) extrDistVal = cmds.floatField(v=-0.3) 

    Во-вторых, при создании типов управления пользовательского интерфейса флаг «command» ищет строку, поэтому вам нужно обернуть команду и ее аргументы в цитате:

     cmds.button(label="Apply", command='superExtrude(extrScaleVal, extrDistVal)') 

    Измените эти три строки, и все должно работать нормально.

    Советы:

    Чтобы прокомментировать одну строку кода, используйте # вместо включения всей строки в тройных одинарных кавычках. Использование тройных кавычек более удобно для комментирования многих строк кода.

    Еще один совет для командных флагов управления: вы можете определить строковую переменную для передачи команд и напрямую использовать переменную вместо строки. Этот трюк пригодится при создании динамических элементов управления, т. Е. Сборе команд на основе пользовательских настроек:

     comStr = "superExtrude(extrScaleVal, extrDistVal)" cmds.button(label="Apply", command=comStr) 

    поэтому я переключил все на pymel, в котором вы должны учиться. cmds – это мусор. найдите время, чтобы посмотреть на различия между вашим и моим. такие скрипты помогут вам начать работу. если мне понадобится дальнейшее объяснение, дайте мне знать.

    сделайте это в пользу и узнайте pymel

    pymel online docs = http://download.autodesk.com/global/docs/maya2014/en_us/PyMel/

     import pymel.core as pm def superExtrude(*args): """Loops through a list of selected meshes and extrudes all of the mesh faces to produce a polygon frame, based on existing mesh tesselations""" #pymel uses python classes to make things easier #its ok to not understand what a class is but just think of it the same as if you were to add an attribute to a polycube. #your code variable now has attributes #so with that pymel ls returns a list of PyNodes that correspond to the objects #cmds ls returns a list of strings which is very unuseful #if you look at the help docs you can find most of whats available myObjectLt = pm.ls(selection=True) for i in myObjectLt: #instead of cycling through by a number were gonna cycle through the list itself #i is now the item in the list #its unnecessary to select the objects because we can specify it in the polyExtrude #cmds.select(item, replace=True) #the extrude commands selects things but im not sure what your trying to achive here by seperating #the scale extrude and translate extrude pm.select(cl=True) #the way poly objects wrok is that you have a transform node and a shape node # if you graph it in the hypershade you'll see the two nodes #the faces are part of the shape node i like accessing things by this node but just know you can do it like this #if <-- f is your attribute and i is the item #using i.getShape() returns the shape node # http://download.autodesk.com/global/docs/maya2014/en_us/PyMel/generated/classes/pymel.core.uitypes/pymel.core.uitypes.FloatField.html?highlight=floatfield#pymel.core.uitypes.FloatField #since were using pymel the extrScaleVal has function that lets you get the value thisScale = extrScaleVal.getValue() pm.polyExtrudeFacet(i.getShape().f, constructionHistory=True, keepFacesTogether=False, localScaleX=thisScale, localScaleY=thisScale, localScaleZ=thisScale) #selFaces = cmds.ls(selection=True) pm.delete() #same as before thisDist = extrDistVal.getValue() #extrude by height pm.polyExtrudeFacet(i.getShape().f, constructionHistory=True, keepFacesTogether=True, localTranslateZ=thisDist) def extrWindow(): #global is a way to transfer variables from function to function the way you had it # you would have had to query the value from your parameters in superExtrude #instead do this global extrScaleVal, extrDistVal #which will makes these parameters to the other function """Creates the user interface UI for the user input of the extrusion scale and height""" windowID = "superExtrWindow" #instead of having a query run just use try except #which will just go to except when the try fails try: pm.deleteUI(windowID) except: pass pm.window(windowID, title="SuperExtrude", sizeable=False, resizeToFitChildren=True) pm.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,120),(2,120)], columnOffset=[1,"right",3]) pm.text(label="Extrusion Scale:") extrScaleVal = pm.floatField(v=0.9) pm.text(label="Extrusion Height:") extrDistVal = pm.floatField(v=-0.3) pm.separator(height=10, style="none") pm.separator(height=10, style="none") pm.separator(height=10, style="none") pm.button(label="Apply", c=superExtrude) pm.showWindow() extrWindow() 
    Python - лучший язык программирования в мире.