Maya UI - I'm sure it's easy once one knows how.

906 views
Skip to first unread message

Chris Mills

unread,
Jan 21, 2010, 12:16:58 AM1/21/10
to python_in...@googlegroups.com
Greetings,

I am trying to build a very simple UI - a window with a button which
then closes the window. No matter what I do, or how I try to format it,
I can not figure out how to get the button command to work. Can someone
please show me what the code should look like for this to happen? If I
can see this, then I suspect I can figure out how to ask the other
questions which I may have, or at least where to start looking in the
various Python resources so I can keep teaching myself.

#### Here is my Python Script which is named "cm_mayaUI_dev_01.py" ####

import string
import maya.cmds as cmds

class CM_ui():

def __init__(self):
print '\nResult: cm_mayaUI_dev_01 initialized.'
self.version = "0.0.0"

# Make Window
def makeWindow(self):
print "Make window now."
cmWin = cmds.window( title="Long Name", iconName='Short Name',
widthHeight=(200, 80) )
cmds.columnLayout( adjustableColumn=True )
cmds.button( label='Close', command=( 'closeWindow()' ) )
cmds.setParent( '..' )
cmds.showWindow( cmWin )

# Close Window Button
def closeWindow(self):
print "Close window."
cmds.deleteUI( self, window=True )


>From inside Maya I used the following in a Python script editor window:

try: cm_mayaUI_dev_01
except:
import cm_mayaUI_dev_01
else:
reload(cm_mayaUI_dev_01)

# Initialize
x = cm_mayaUI_dev_01.CM_ui()
x.makeWindow()

The window is created when I run this, but when I press the button I get
an error in Maya:
# Error: NameError: name 'closeWindow' is not defined #

Thanks very much in advance.

Stumped and very confused as to what I am missing,
Chris Mills

Lizard Lounge Graphics, LTD.
Wellington, NZ
http://lizardlounge.com

Int'l: +644-977-5400 / +642-174-8770
NZ local: 04-977-5400 / 021-748-770

Seth Gibson

unread,
Jan 21, 2010, 12:24:12 AM1/21/10
to python_in...@googlegroups.com
Try this.  It's not very elegant and there are probably better architectural decisions you could make, but it should get you pointed in the right direction:


import string
import maya.cmds as cmds

class CM_ui():
    def __init__(self):
        print '\nResult: cm_mayaUI_dev_01 initialized.'
        self.version = "0.0.0"
        self.cmWin = None


    def makeWindow(self):
        print "Make window now."
        self.cmWin = cmds.window( title="Long Name", iconName='Short Name',widthHeight=(200, 80) )
        cmds.columnLayout( adjustableColumn=True )
        cmds.button( label='Close', command=self.closeWindow )
        cmds.setParent( '..' )
        cmds.showWindow( self.cmWin )

    # Close Window Button
    def closeWindow(*args):
        print "Close window."
        cmds.deleteUI( args[0].cmWin, window=True )


Chris Mills

unread,
Jan 21, 2010, 12:48:32 AM1/21/10
to python_in...@googlegroups.com
Thank you Seth!

Kind regards,
Chris

Lizard Lounge Graphics, LTD.
Wellington, NZ
http://lizardlounge.com

Int'l: +644-977-5400 / +642-174-8770
NZ local: 04-977-5400 / 021-748-770

AK Eric

unread,
Jan 21, 2010, 11:34:04 AM1/21/10
to python_inside_maya
Just to add a bit more: The below block of code is one I just stick
on my shelf, and drag it down to the script editor any time I want to
start a new window. Like Seth, I just modified it to add a button to
close the window as well.

The finicky bit are button commands, or any command executed from a
control: They only expect to execute a string, or a function *name*,
without args. Things get more complex if you want want to pass args
from your button to your command/method, and like Seth showed you can
use *args to help capture them on the method side. Furthermore, even
if you don't want to capture args from your command execution, Maya
likes to pass out a default value upon execution which your command
must be able to intercept, again, via *args. If you're interested in
the specifics of that, I have a couple tutorials\notes here:
http://mayamel.tiddlyspot.com/#[[Positional%20args%20in%20Python%20authored%20UI%27s]]
http://mayamel.tiddlyspot.com/#[[Executing%20external%20functions%20via%20UI%27s%20authord%20in%20Python]]
Which basically show how to use lambda or functools.partial


__version__ = '0.1'

import maya.cmds as mc

class App(object):
def __init__(self):
self.name = "pyWin"
self.title = "Python Window"

if mc.window(self.name, exists=True):
mc.deleteUI(self.name)

self.window = mc.window(self.name, title=self.title+" - v"
+__version__, resizeToFitChildren=True)
self.rootLayout = mc.columnLayout(adjustableColumn=True,
columnAttach=('both', 5))

self.button = mc.button(label="Close Window",
command=self.buttonCmd)

mc.showWindow()

def buttonCmd(self, *args):
mc.deleteUI(self.name)

App()


On Jan 20, 9:48 pm, Chris Mills <c...@lizardlounge.com> wrote:
> Thank you Seth!
>
> Kind regards,
> Chris
>
> Lizard Lounge Graphics, LTD.

> Wellington, NZhttp://lizardlounge.com

ryant

unread,
Jan 21, 2010, 4:25:33 PM1/21/10
to python_inside_maya
I have not seen it posted so I thought I would mention there are other
options for passing callable functions as well. You can use a partial
function to create a callable function to a command.

Example:

from functools import partial

def myfunc(does, some=1, stuff='test'):
print does
print some
print stuff


part = partial(myfunc, 10, some=10, stuff='ten')
part()

# Result #
10
10
ten
# End Result #

By using the partial function you can pass a button a partial function
with whatever arguments you need to pass:

self.button = mc.button(label="Close Window", command=partial
(self.buttonCmd, 'pass', my='arguments', into='something')


Ryan
Character TD
www.rtrowbridge.com/blog
NaughtyDog Inc.

ryant

unread,
Jan 21, 2010, 4:49:56 PM1/21/10
to python_inside_maya
I guess you can use a lambda also which I didnt know Eric. I gave you
a seventh solution to put on your site.

Ryan
Character TD
www.rtrowbridge.com/blog
NaughtyDog Inc.

AK Eric

unread,
Jan 21, 2010, 5:30:07 PM1/21/10
to python_inside_maya
Yeh, you know, lambdas work often, but not always. I've found that if
I have a procedurally generated UI... say, looping to make a lot of
buttons, and each should have some unique argument passed into the
executed command, lambda will assign the same args to every button
(bad), but functools.partial will pass in the uniqe args (good). So I
sort of use a mix of the two depending on the situation. I haven't
tried troubleshooting why that is though ;)

On Jan 21, 1:49 pm, ryant <ad...@rtrowbridge.com> wrote:
> I guess you can use a lambda also which I didnt know Eric. I gave you
> a seventh solution to put on your site.
>
> Ryan

damon shelton

unread,
Jan 21, 2010, 6:02:23 PM1/21/10
to python_in...@googlegroups.com
Eric,
here is how you can handle the looping lambda issue
set one of your lamdas (eg. y in this case to equal the argument)

import maya.cmds as cmds

class lambdaLoop():
    def __init__(self, values = ['a', 'b', 'c']):
        self.window = 'lambdaLoop_win'
        self.vals = values
       
    def Window(self):
        if cmds.window(self.window, ex = True):
            cmds.deleteUI(self.window)
           
        self.window = cmds.window(self.window, w = 200, h = len(self.vals * 20))
        layout = cmds.columnLayout(p = self.window, adj = True)
       
        for i in xrange(0, len(self.vals)):
            cmds.button(p = layout, l = self.vals[i], c = (lambda x, y == i:self.command(arg = y)))
           
        cmds.showWindow(self.window)
       
    def command(self, arg):
        print self.vals[arg]

-Damon


damon shelton

unread,
Jan 21, 2010, 6:04:31 PM1/21/10
to python_in...@googlegroups.com
sorry, y = i not y == i

On Thu, Jan 21, 2010 at 3:02 PM, damon shelton <damond...@gmail.com> wrote:
Eric,
here is how you can handle the looping lambda issue
set one of your lamdas (eg. y in this case to equal the argument)


import maya.cmds as cmds

class lambdaLoop():
    def __init__(self, values = ['a', 'b', 'c']):
        self.window = 'lambdaLoop_win'
        self.vals = values
       
    def Window(self):
        if cmds.window(self.window, ex = True):
            cmds.deleteUI(self.window)
           
        self.window = cmds.window(self.window, w = 200, h = len(self.vals * 20))
        layout = cmds.columnLayout(p = self.window, adj = True)
       
        for i in xrange(0, len(self.vals)):
            cmds.button(p = layout, l = self.vals[i], c = (lambda x, y = i:self.command(arg = y)))

AK Eric

unread,
Jan 21, 2010, 8:46:40 PM1/21/10
to python_inside_maya
Hey, nice! Mystery solved ;)

On Jan 21, 3:04 pm, damon shelton <damondshel...@gmail.com> wrote:
> sorry, y = i not y == i
>

Reply all
Reply to author
Forward
0 new messages