简体   繁体   中英

Maya Python: OptionMenu Selection With Button

I'm new to python in Maya and I'm trying to build a UI which can generate shapes and transform them. The problem I think lies in the ObjectCreation function but I'm not to sure. So far this what I've got:

import maya.cmds as cmds

#check to see if window exists
if cmds.window("UserInterface", exists = True):
    cmds.deleteUI("UserInterface")
#create actual window
UIwindow = cmds.window("UserInterface", title = "User Interface Test", w = 500, h = 700, mnb = False, mxb = False, sizeable = False)
mainLayout = cmds.columnLayout(w = 300, h =500)

def SceneClear(*args):
    cmds.delete(all=True, c=True) #Deletes all objects in scene
cmds.button(label = "Reset", w = 300, command=SceneClear)

polygonSelectMenu = cmds.optionMenu(w = 250, label = "Polygon Selection:")
cmds.menuItem(label = " ")
cmds.menuItem(label = "Sphere")
cmds.menuItem(label = "Cube")
cmds.menuItem(label = "Cylinder")
cmds.menuItem(label = "Cone")

def ObjectCreation(*args):
    if polygonSelectMenu.index == 2: #tried referring to index
        ma.polySphere(name = "Sphere")
    elif polygonSelectMenu == "Cube":
        ma.polyCube(name = "Cube")
    elif polygonSelectMenu == "Cylinder":
        ma.polyCylinder(name = "Cylinder")
    elif polygonSelectMenu == "Cone":
        ma.polyCone(name = "Cone")
cmds.button(label = "Create", w = 200, command=ObjectCreation)

def DeleteButton(*args):
    cmds.delete()
cmds.button(label = "Delete", w = 200, command=DeleteButton)#Deletes selected object   

cmds.showWindow(UIwindow) #shows window

What I'm after is for the user to select one of the options from the option menu then to press the create button to generate that shape. I've tried to refer to it by name and index but I don't know what I'm missing. Like I said I'm new to python so when I tried searching for an answer myself I couldn't find anything and when I did find something similar I couldn't understand it. Plus for some reason the SceneClear function/Reset button doesn't seem to work so if there is answer to that please let me know.

polygonSelectMenu contains the path to your optionMenu UI element. In my case it is: UserInterface|columnLayout7|optionMenu4 . This is just a string and not a reference to a UI element.

To access it's current value you must use this:

currentValue = cmds.optionMenu(polygonSelectMenu, query=True, value=True)

All optionMenu's flags are listed here (Maya 2014 commands doc) , queryable ones have a little green Q next to them.


As a result, here is your ObjectCreation(*args) function:

def ObjectCreation(*args):
    currentValue = cmds.optionMenu(polygonSelectMenu, query=True, value=True)
    if currentValue == "Sphere": #tried referring to index
        cmds.polySphere(name = "Sphere")
    elif currentValue == "Cube":
        cmds.polyCube(name = "Cube")
    elif currentValue == "Cylinder":
        cmds.polyCylinder(name = "Cylinder")
    elif currentValue == "Cone":
        cmds.polyCone(name = "Cone")

Off-topic:

Avoid declaring functions between lines of code (in your case, the UI creation code), try instead putting the UI creation code inside a function and call this function at the end of your script.

It is readable as you have only few UI elements right now. But once you start having 20 or more buttons/labels/inputs it can be a mess quickly.

Also, I prefer giving an object name to the UI elements, just like you did with your window ( "UserInterface" ). To give you a concrete example: cmds.optionMenu("UI_polygonOptionMenu", w = 250, label = "Polygon Selection:") This optionMenu can be then accessed anywhere in you code using: cmds.optionMenu("UI_polygonOptionMenu", query=True, value=True)

Here is the full modified script if you want:

import maya.cmds as cmds

def drawUI(): #Function that will draw the entire window
    #check to see if window exists
    if cmds.window("UI_MainWindow", exists = True):
        cmds.deleteUI("UI_MainWindow")
    #create actual window
    cmds.window("UI_MainWindow", title = "User Interface Test", w = 500, h = 700, mnb = False, mxb = False, sizeable = False)
    cmds.columnLayout("UI_MainLayout", w = 300, h =500)

    cmds.button("UI_ResetButton", label = "Reset", w = 300, command=SceneClear)

    cmds.optionMenu("UI_PolygonOptionMenu", w = 250, label = "Polygon Selection:")
    cmds.menuItem(label = " ")
    cmds.menuItem(label = "Sphere")
    cmds.menuItem(label = "Cube")
    cmds.menuItem(label = "Cylinder")
    cmds.menuItem(label = "Cone")

    cmds.button("UI_CreateButton", label = "Create", w = 200, command=ObjectCreation)
    cmds.button("UI_DeleteButton", label = "Delete", w = 200, command=DeleteButton)#Deletes selected object   

    cmds.showWindow("UI_MainWindow") #shows window

def SceneClear(*args):
    cmds.delete(all=True, c=True) #Deletes all objects in scene

def ObjectCreation(*args):
    currentValue = cmds.optionMenu("UI_PolygonOptionMenu", query=True, value=True)
    if currentValue == "Sphere": 
        cmds.polySphere(name = "Sphere")
    elif currentValue == "Cube":
        cmds.polyCube(name = "Cube")
    elif currentValue == "Cylinder":
        cmds.polyCylinder(name = "Cylinder")
    elif currentValue == "Cone":
        cmds.polyCone(name = "Cone")

def DeleteButton(*args):
    cmds.delete()

drawUI() #Calling drawUI now at the end of the script

Hope this will help you.

as said above the maya.cmds works very much like mel and you have to use the command cmds.optionMenu() with the polygonSelectMenu as the first arg.

Alternatively if you use pymel instead, you could access the class attrs of polygonSelectMenu with the dot operator like:

import pymel.core as pm

if pm.window("UserInterface", exists = True):
    pm.deleteUI("UserInterface")

UIwindow = pm.window("UserInterface", title = "User Interface Test", w = 500, h = 700, mnb = False, mxb = False, sizeable = False)
mainLayout = pm.columnLayout(w = 300, h =500)
polygonSelectMenu = pm.optionMenu(w = 250, label = "Polygon Selection:")
pm.menuItem(label = " ")
pm.menuItem(label = "Sphere")
pm.menuItem(label = "Cube")
pm.menuItem(label = "Cylinder")
pm.menuItem(label = "Cone")
pm.button(label = "Create", w = 200, command=ObjectCreation)
UIwindow.show()


def ObjectCreation(*args):
    print polygonSelectMenu.getValue()

also you could make the program into a class with a drawUI method, which might make it easy to do things like store all the items you create in ObjectCreation inside of a class attr so that you can just delete them with your reset button (as i noticed you have cmds.delete(all=True) which i think is not supported anymore in maya), or store the UI elements in self.ui_element. That way they can be referenced later as the variable without the possible conflicts from having multiple windows open that all have buttons like "UI_CreateButton" or "okButton" etc...

import maya.cmds as cmds

class UI_Test_thingy():
    windowName = 'UserInterface'
    version = 'v1.1.1'
    debug = True
    createdThingys = []

    def __init__(self):
        self.drawUI()


    def drawUI(self):
        if UI_Test_thingy.debug: print 'DEBUG - drawUI called'
        #check to see if window exists
        try:
            cmds.deleteUI(UI_Test_thingy.windowName)

        except:
            pass

        #create actual window
        UIwindow = cmds.window(UI_Test_thingy.windowName, title = "User Interface Test {}".format(UI_Test_thingy.version), w = 500, h = 700, mnb = False, mxb = False, sizeable = False)
        mainLayout = cmds.columnLayout(w = 300, h =500)
        cmds.button(label = "Reset", w = 300, command=self.SceneClear)

        self.polygonSelectMenu = cmds.optionMenu(w = 250, label = "Polygon Selection:")
        cmds.menuItem(label = " ")
        cmds.menuItem(label = "Sphere")
        cmds.menuItem(label = "Cube")
        cmds.menuItem(label = "Cylinder")
        cmds.menuItem(label = "Cone")

        cmds.button(label = "Create", w = 200, command=self.ObjectCreation)

        cmds.button(label = "Delete", w = 200, command=self.DeleteButton)#Deletes selected object   

        cmds.showWindow(UIwindow) #shows window


    def DeleteButton(self, *args):
        if UI_Test_thingy.debug: print 'DEBUG - DeleteButton called: args: {}'.format(args)
        cmds.delete()


    def SceneClear(self, *args):
        if UI_Test_thingy.debug: print 'DEBUG - SceneClear called: args: {}'.format(args)
        thingsToDel = UI_Test_thingy.createdThingys[:] # copy the list of things created by this script
        UI_Test_thingy.createdThingys = [] # reset the list before deleteing the items
        print 'deleteing: {}'.format(thingsToDel)
        if thingsToDel:
            cmds.delete( thingsToDel ) #Deletes all objects created by this script

    def ObjectCreation(self, *args):
        if UI_Test_thingy.debug: print 'DEBUG - ObjectCreation called: args: {}'.format(args)
        menuVal = cmds.optionMenu(self.polygonSelectMenu, q=True, value=True)
        if menuVal == "Sphere": 
            UI_Test_thingy.createdThingys += cmds.polySphere(name = "Sphere") # store the results to the class attr createdThingys
        elif menuVal == "Cube":
            UI_Test_thingy.createdThingys += cmds.polyCube(name = "Cube") # store the results to the class attr createdThingys
        elif menuVal == "Cylinder":
            UI_Test_thingy.createdThingys += cmds.polyCylinder(name = "Cylinder") # store the results to the class attr createdThingys
        elif menuVal == "Cone":
            UI_Test_thingy.createdThingys += cmds.polyCone(name = "Cone") # store the results to the class attr createdThingys


if __name__ == '__main__':
    ui = UI_Test_thingy()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM