So I'm trying to output the label of the button as it's pressed (Button label should replace the XXX in the print of the buttonNumber function). I do not know how to retrieve the label data from the button to output. Any thoughts? Thanks in advance
import maya.cmds as mc
def buttonNumber(*args):
print 'Button XXX was pressed'
def openWindow():
if mc.window('windowTest', ex=True):
mc.deleteUI('windowTest', window=True)
mc.window('windowTest', title='', s=True, resizeToFitChildren = True,)
mc.rowColumnLayout(numberOfColumns = 3, columnWidth = [ (1, 150), (2, 150), (3, 150)])
mc.button(label='1', command=buttonNumber)
mc.button(label='2', command=buttonNumber)
mc.button(label='3', command=buttonNumber)
mc.button(label='4', command=buttonNumber)
mc.button(label='5', command=buttonNumber)
mc.button(label='6', command=buttonNumber)
mc.button(label='7', command=buttonNumber)
mc.button(label='8', command=buttonNumber)
mc.button(label='9', command=buttonNumber)
mc.showWindow('windowTest')
openWindow()
I did a little reminder on my blog some time ago, to be able to test all the different native Maya UI way of using commands with a fast way of testing them:
Each case is also given with examples with passing variables as arguments to those functions. Because sometimes you have to be able to. Overall I totally recommend the use functools.partial, it gives only advantages over the others (if you forget about PySide).
Maya UI types
When using a class
Because it was not made with the use of class in mind, some ways does not work at all when you are in a class.
Here's my code that does what you need.
Instead of hard-coding the argument of the label of each button to pass to the function at button creation time, I pass the object name of the button into the function. This way, all attributes of the button (including the label) can be queried at any point.
To show this I made a randomise function that generates random alphanumeric strings and assigns them to the button labels.
It'll entertain you for 30 seconds. Try it!
As @DeWeeny says, you can bind a value to the button commands with a
functools.partial
object. You could also do it with a function factory for this very simple application, or with a callable class that remembered a value for each instance.function factory
The only subtlety there is that
inner_callback
has an unused argument (the_
) which it needs because button callbacks always fire a useless parameterclass
This is useful if the data is more complex or needs more calculation than in the function factory example
This is functionally identical but if you had to do something with more complex behavior a class would make it tidy
not lambda
You may find advice on the web to do it with a
lambda
. For lots of applications that would be great -- but don't do it in a loop. If you do this:All the buttons will respond
because the lambdas will all capture the last variable in the loop which is not what you want.
More details here. And a maya-specific module for exactly this sort of thing here
I recommend you to read my other posts on stackoverflow about Partial (note that there is another method with Lambda)
I didn't test the code below (I don't have maya here but you will get the idea)