Reputation: 890
I am trying to build a GUI that has three horizontal sliders that control some probability. Each slider can range between 0 - 1.0 but all three together must equal 1.0 at all times. Here is a link I found that does what I want but with jQuery.
Is there any good way of doing this in Qt? PyQt more specifically but I think pseudo code will suffice.
Upvotes: 3
Views: 3524
Reputation: 34116
class MainWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
layout = QGridLayout()
self.sliders = []
slider_amount = 3
slider_precision = 10000 # sliders work only with ints, so large ints are used and mapped to floats
for i in range(slider_amount):
slider = QSlider(Qt.Horizontal)
slider.setRange(0, slider_amount*slider_precision)
slider.setSingleStep(slider.maximum()/100.0)
slider.setPageStep(slider.maximum()/20.0)
slider.valueChanged.connect(self.on_slider_value_changed)
slider.float_value = (i+1)/((1+slider_amount)/2.0*slider_amount) # provide your own default values
slider.label = QLabel()
self.sliders.append(slider)
layout.addWidget(slider, i, 0)
layout.addWidget(slider.label, i, 1)
self.update_slider_values()
self.setLayout(layout)
self.show()
def on_slider_value_changed(self, value):
changed_slider = self.sender()
changed_slider.float_value = float(value)/changed_slider.maximum()
delta = sum(slider.float_value for slider in self.sliders)-1
while abs(delta)>0.00001:
d = len(self.sliders)-1
for slider in self.sliders:
if slider is changed_slider:
continue
old_value = slider.float_value
slider.float_value = min(max(0, old_value-delta/d), 1)
delta -= old_value-slider.float_value
d -= 1
self.update_slider_values()
def update_slider_values(self):
for slider in self.sliders:
slider_signals_blocked = slider.blockSignals(True)
slider.setValue(round(slider.float_value*slider.maximum()))
slider.blockSignals(slider_signals_blocked)
slider.label.setText('{:.2f}'.format(slider.float_value))
app = QApplication(sys.argv)
mw = MainWindow()
app.exec_()
Upvotes: 3
Reputation: 2621
You would have to connect the valueChanged
signal of the sliders to a slot you define yourself. In this slot (function) you can implement the calculation of the new values of all sliders and use the setValue
slot to apply the new values.
Upvotes: 0