Maya Python:cmds.button(),UI传递变量并调用函数?

St4*_*b0y 0 python maya pymel

首先,这似乎是一个学习更多编程的好地方.我编写了一个maya python脚本,其中两个函数都有效,但我无法通过UI按钮来调用superExtrude()函数.第一个函数执行几何网格操作,第二个函数应该为用户输入生成UI:

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()
Run Code Online (Sandbox Code Playgroud)

我是python和maya脚本的新手,所以任何帮助都会非常感激.:)

Ben*_*Ben 7

我不确定这是否是您想要的答案,但您必须了解maya"命令"标志:

  • 如果要在按钮调用中放置函数,则需要传入函数名而不带任何参数(例如:command = myFunction)(去掉结尾括号"()")

  • 在你的函数中,你需要添加一个"*args",因为maya按钮总是传递一个参数(我认为它是"False")(例如:def myFunction(customArg1,customArg2,*args))

  • 如果你想在按钮信号中传递参数,你需要使用functools模块中的partial函数(来自functools import partial)并使用它如下:cmds.button(command = partial(myFunction,arg1,arg2,kwarg1 = value1,kwarg2 = value2))

还有一件事,关于pymel和cmds ......它可能是一个永无止境的故事,但pymel并不是万能的...当你必须处理很多信息时(比如在网格上获取顶点列表),pymel可能是某种东西比简单的maya命令慢40倍.它有它的优点和缺点......如果你刚刚开始使用python,我现在不建议你进入pymel.熟悉语法和命令,当你没问题时,切换到pymel(在处理对象创建时非常有用)

希望这有所帮助,干杯

编辑:

根据您的第一篇文章,您需要更改代码才能使其正常工作:

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()
Run Code Online (Sandbox Code Playgroud)


Kev*_*vin 6

cmds.button(label="Apply", command=superExtrude(extrScaleVal, extrDistVal))
Run Code Online (Sandbox Code Playgroud)

此行调用superExtrude并将其返回值赋值给command.由于superExtrude没有返回任何东西,按钮实际上有一个共同点None.

也许你打算在superExtrude单击按钮时调用它,在这种情况下你应该将它包装在lambda中以防止它被立即调用:

cmds.button(label="Apply", command=lambda *args: superExtrude(extrScaleVal, extrDistVal))
Run Code Online (Sandbox Code Playgroud)