Many widgets include events which can fire callback functions when the user interacts with the widget. For example when a button is pressed, a checkbox checked, or a dropdown chosen you can fire a function.
The exact flag which is associated with these event depends on the widget, but a typical callback would look like this:
def callback_fn(_ignore):
print "button pressed"
button = cmds.button(label='press me', command = callback_fn)
Pressing the button will print "button pressed" to the listener window. Most widget's fire some arguments when their callbacks activate -- the button
for example always includes a boolean value -- so you'll need to make sure that the callback handler has the right signature to go with the widget you're using. That's why callback_fn()
takes an argument even though it doesn't need it.
Maya supports two different ways of attaching callback functions:
# this works, but is not a great idea
cmds.button(label = 'string reference', command = 'string_name_of_function')
# use this form whenever possible
cmds.button(label = 'direct function reference', command = callback_fn)
In the first example the callback is assigned by a string value. Maya will find the callback in the global Python scope -- which is usually hard to access when writing properly organized code. String-name callbacks are also slower to resolve. The second example passes the actual Python function to the callback -- this form is preferred because it is faster and, if you've failed to provide a valid function to the callback function, you'll know when the UI is created instead of when the UI widgets are actually used.
If you want to pass a argument value to a call back function, you can use a lambda, a closure or a functools.partial bind arguments to the callback.
partial
: from functools import partial
....
def callback_fn(myValue, _ignore): # _ignore swallows the original button argument
print myValue
button = cmds.button(label='press me', command = partial(callback_fn, "fooo"))
lambda
: def callback_fn(myValue):
print myValue
button = cmds.button(label='press me', command = lambda _ignore: callback_fn("fooo"))
# here the lambda needs to handle the button argument
b = cmds.button(label = 'press me')
# by defining this function when `b` exists, we can use it later
# without storing it explicitly
def get_button_label(*_):
print "label of button", b, " is ", cmds.button(b, q=True, l=True)
cmds.button(b, e=True, c=get_button_label)
There' more about string callback names vs. callback function here