Reputation: 418
I'm trying to get a scale slider steup, and whenever I change the slider value, I'd like for the new value to be printed out:
scaleSlider = cmds.floatSliderGrp(label='Curve Scale',
field=True,
minValue=0.0,
maxValue=2.0,
fieldMinValue=0.0,
fieldMaxValue=2.0,
value=1,
cc="print cmds.floatSliderGrp(scaleSlider, q=True, v=True)" )
This seems pretty simple, but I'm getting this error:
// Error: name 'scaleSlider' is not defined
# Traceback (most recent call last):
# File "<maya console>", line 1, in <module>
# NameError: name 'scaleSlider' is not defined //
The error is not very descriptive, unfortunately. I'm having trouble tracking down what the issue might be. At first I thought it was self-referential, but the error would tell me if so, correct?
Upvotes: 0
Views: 1557
Reputation: 12218
Your problem is in the cc
argument.
First, you've passed a statement not a function: you'd need to wrap the whole thing in a def or a lambda to work correctly. Second, you're passing it a string reference to scaleSlider
, but at the time the callback is defined that variable doesn't exist. There are circumstances under which this code would work and others under which it won't (inside a function, for example, it will fail). Using string callback arguments is an invitation to these kinds of problems.
It's easier to do it like this:
w = cmds.window()
c = cmds.columnLayout()
s = cmds.floatSliderGrp("example")
def callback(*_):
print s, "=", cmds.floatSliderGrp(s, q=True, v=True)
cmds.floatSliderGrp(s, e=True, cc=callback)
cmds.showWindow(w)
Because callback
is defined after cmds.floatSliderGrp("example")
has executed, it knows the value of s
(don't use single-letter variables in real code!) . Because cmds.floatSliderGrp(s, e=True, cc=callback)
executes after that, it passes the version of the callback which knows the correct value of s
to this particular float slider group. This example will work in the listener or wrapped inside a function because the scoping is consistent.
@AriGold's solution will also work, although lambdas
can't be used in a loop -- if you tried to run his solution in a loop all of the callbacks may end up pointing at the last UI element because lambda's bind very late.
Lots more detail on the different ways to set up UI callbacks here
Upvotes: 1
Reputation: 1548
work with dict and lambda,
def get_ui_value(ui_id, ui_type):
mcds = globals()["cmds"]
method = getattr(mcds, ui_type)
print method(ui_id, q=True, v=True)
ui_dict = {}
ui_dict["flt_slider_xy"] = cmds.floatSliderGrp(label='Curve Scale',
field=True,
minValue=0.0,
maxValue=2.0,
fieldMinValue=0.0,
fieldMaxValue=2.0,
value=1)
ui_dict["int_slider_xy"] = cmds.intSliderGrp(label='Curve Scale',
field=True,
minValue=0,
maxValue=10,
fieldMinValue=0,
fieldMaxValue=2,
value=1)
cmds.floatSliderGrp(ui_dict["flt_slider_xy"], e=True, cc= (lambda message:get_ui_value(ui_dict[flt_slider_xy], "floatSliderGrp")))
cmds.floatSliderGrp(ui_dict["int_slider_xy"], e=True, cc= (lambda message:get_ui_value(ui_dict[int_slider_xy], "intSliderGrp")))
Upvotes: 2