[Maya UI]Setting up sliders that normalize to 100

Hi,
I’m trying to setup a UI that contains any number of sliders (it’s dynamically built), that when you slide one slider, the others update to make sure the sum total of all the sliders is equal to 100.
Like how the Humble Bundle sliders work : https://www.humblebundle.com/ (step 2, at bottom)
Right now with my code (below), all sliders normalize to 100 but they all snap to the same value. I want to be able to add or subtract from the current value, but I’m not sure how to determine if the active slider is increasing or decreasing in value.

Here’s my code so far:

build generic MAYA examples floatSliderGrp window
window = cmds.window(title=‘floatSliderGrp Example’)
cmds.columnLayout()
cmds.floatSliderGrp(‘Group1’, label=‘Group 1’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group1”)’ )
cmds.floatSliderGrp(‘Group2’, label=‘Group 2’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group2”)’ )
cmds.floatSliderGrp(‘Group3’, label=‘Group 3’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group3”)’ )
cmds.floatSliderGrp(‘Group4’, label=‘Group 4’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group4”)’ )
cmds.showWindow( window )

def normalize_slider_weights(self) :
print(self)
groups = [‘Group1’,‘Group2’,‘Group3’,‘Group4’]
values = {}
self_value = 0
for group in groups :
if group == self :
self_value = cmds.floatSliderGrp(group, q=1, v=1)
final_value = (100 - self_value) / 4
print final_value
for group in groups :
if group == self :
continue
cmds.floatSliderGrp(group, e=1, v=final_value)

Thanks for taking a look!
Adrian

[QUOTE=Age914;22763]Hi,
I’m trying to setup a UI that contains any number of sliders (it’s dynamically built), that when you slide one slider, the others update to make sure the sum total of all the sliders is equal to 100.
Like how the Humble Bundle sliders work : https://www.humblebundle.com/ (step 2, at bottom)
Right now with my code (below), all sliders normalize to 100 but they all snap to the same value. I want to be able to add or subtract from the current value, but I’m not sure how to determine if the active slider is increasing or decreasing in value.

Here’s my code so far:

build generic MAYA examples floatSliderGrp window
window = cmds.window(title=‘floatSliderGrp Example’)
cmds.columnLayout()
cmds.floatSliderGrp(‘Group1’, label=‘Group 1’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group1”)’ )
cmds.floatSliderGrp(‘Group2’, label=‘Group 2’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group2”)’ )
cmds.floatSliderGrp(‘Group3’, label=‘Group 3’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group3”)’ )
cmds.floatSliderGrp(‘Group4’, label=‘Group 4’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group4”)’ )
cmds.showWindow( window )

def normalize_slider_weights(self) :
print(self)
groups = [‘Group1’,‘Group2’,‘Group3’,‘Group4’]
values = {}
self_value = 0
for group in groups :
if group == self :
self_value = cmds.floatSliderGrp(group, q=1, v=1)
final_value = (100 - self_value) / 4
print final_value
for group in groups :
if group == self :
continue
cmds.floatSliderGrp(group, e=1, v=final_value)

Thanks for taking a look!
Adrian[/QUOTE]

Figured it out, with this code I wrote:
window = cmds.window(title=‘floatSliderGrp Example’)
cmds.columnLayout()
cmds.floatSliderGrp(‘Group1’, label=‘Group 1’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group1”)’, cc=‘normalize_slider_weights(“Group1”)’ )
cmds.floatSliderGrp(‘Group2’, label=‘Group 2’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group2”)’, cc=‘normalize_slider_weights(“Group2”)’ )
cmds.floatSliderGrp(‘Group3’, label=‘Group 3’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group3”)’, cc=‘normalize_slider_weights(“Group3”)’ )
cmds.floatSliderGrp(‘Group4’, label=‘Group 4’, field=True, minValue=-0, maxValue=100, value=25, dc=‘normalize_slider_weights(“Group4”)’, cc=‘normalize_slider_weights(“Group4”)’ )
cmds.showWindow( window )

def normalize_slider_weights(self) :
values =
groups = [‘Group1’,‘Group2’,‘Group3’,‘Group4’]
for group in groups :
values.append(cmds.floatSliderGrp(group, q=1, v=1))
total_sum = get_total_sum(values)
cur_values =
if total_sum > 100 :
difference = total_sum - 100
final_value = difference / 3
for group in groups :
cmds.floatSliderGrp(group, e=1, v=(cmds.floatSliderGrp(group, q=1, v=1) - final_value))
if total_sum < 100 :
difference = 100 - total_sum
final_value = difference / 3
for group in groups :
cmds.floatSliderGrp(group, e=1, v=(cmds.floatSliderGrp(group, q=1, v=1) + final_value))

def get_total_sum(values) :
acc = 0
for i in values:
acc += i
return acc

Now I need a way to allow the user to lock out values, I shall start with a floatSliderButtonGrp!

Use CODE tags! Unintended python is difficult to look at

Your current method will produce inaccurate results because you are getting the difference and applying it to all 4 floatSliderGrps, even the one that the user is dragging. You can simplify it quite a bit and get your expected behavior:

window = cmds.window(title='floatSliderGrp Example')
cmds.columnLayout()
cmds.floatSliderGrp('Group1', label='Group 1', field=True, minValue=-0, maxValue=100, value=25, dc='normalize_slider_weights("Group1")', cc='normalize_slider_weights("Group1")' )
cmds.floatSliderGrp('Group2', label='Group 2', field=True, minValue=-0, maxValue=100, value=25, dc='normalize_slider_weights("Group2")', cc='normalize_slider_weights("Group2")' )
cmds.floatSliderGrp('Group3', label='Group 3', field=True, minValue=-0, maxValue=100, value=25, dc='normalize_slider_weights("Group3")', cc='normalize_slider_weights("Group3")' )
cmds.floatSliderGrp('Group4', label='Group 4', field=True, minValue=-0, maxValue=100, value=25, dc='normalize_slider_weights("Group4")', cc='normalize_slider_weights("Group4")' )
cmds.showWindow( window )


def normalize_slider_weights(changed):
    groups = ['Group1','Group2','Group3','Group4']
    values = [cmds.floatSliderGrp(g, q=True, v=True) for g in groups]
    total = sum(values)
    diff = total - 100.0
    change = diff / (len(groups) - 1)
    for i, group in enumerate(groups):
        if group != changed:
            cmds.floatSliderGrp(group, e=True, v=values[i] - change)

Also, this won’t give you the exact behavior of the humble bundle example. On the HB site, once a slider hits 0, it will stay at 0 and won’t dynamically move anymore unless ALL of the sliders except one are at 0. In that case all of the sliders at 0 will move together.

As an aside, when doing grouped controls that need to communicate with each other for a specific purpose, I like to build a class that handles all of the control tracking and dynamic changes. So you would have a class called BalancedFloatSliderGrps or something, and that class would have methods for adding and removing sliders, getting values, changing the max value, etc. That way you have a simple and common interface, and reusable code allowing you to add this dynamically balancing sliderGrp anywhere you want. All the internals are hidden away and generalized, so they won’t confuse or clutter your code.
Then it’s usage could be as simple as:

# Building the widget
balanced_sliders = BalancedFloatSliderGrps()
for name in groupNames:
    balanced_sliders.add(label=name)

# Retrieving values
for name, value in balanced_sliders.get_values():
    print name, value

# Value by label
group2_value = balanced_sliders.get_value(label='Group2')

# Changing the top value
balanced_sliders.set_max_value(50)