62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||
|
|
||
|
__all__ = ['QFloatSlider']
|
||
|
|
||
|
|
||
|
class QFloatSlider(QtWidgets.QSlider):
|
||
|
"""
|
||
|
Subclass of QtWidgets.QSlider
|
||
|
Horizontal slider giving floating point values.
|
||
|
Usage: QFloatSlider(min, max, step, default)
|
||
|
where min = minimum value of slider
|
||
|
max = maximum value of slider
|
||
|
step = interval between values. Must be a factor of (max-min)
|
||
|
default = default (starting) value of slider
|
||
|
"""
|
||
|
def __init__(self, min_value, max_value, step, default):
|
||
|
super().__init__(QtCore.Qt.Horizontal)
|
||
|
self.precision = 0.001
|
||
|
self.min_value = min_value
|
||
|
self.max_value = max_value
|
||
|
self.step = step
|
||
|
self.default = default
|
||
|
self.quotient, self.remainder = self._float_divmod(\
|
||
|
self.max_value-self.min_value, self.step)
|
||
|
if self.remainder:
|
||
|
raise ValueError("{} does not fit evenly between {} and {}"\
|
||
|
.format(step, min_value, max_value))
|
||
|
super().setMinimum(0)
|
||
|
super().setMaximum(self.quotient)
|
||
|
super().setSingleStep(1)
|
||
|
super().setValue(self._float_to_int(self.default))
|
||
|
super().valueChanged.connect(self._value_handler)
|
||
|
self.slider_value = 2.0
|
||
|
|
||
|
# This is mostly disgusting python i hate floating points >:(
|
||
|
def _float_divmod(self,a,b):
|
||
|
"""
|
||
|
Basically the divmod function but it works for floats (try 0.3 % 0.1 smh)
|
||
|
Returns the quotient, and a remainder.
|
||
|
"""
|
||
|
a = abs(a)
|
||
|
b = abs(b)
|
||
|
n = 1
|
||
|
while True:
|
||
|
c = a - b
|
||
|
c = abs(c)
|
||
|
if c < self.precision:
|
||
|
return (n, 0)
|
||
|
elif c > a:
|
||
|
return (n-1, a)
|
||
|
a = c
|
||
|
n += 1
|
||
|
|
||
|
def _float_to_int(self, a):
|
||
|
return int(round(a/self.step))
|
||
|
|
||
|
def _int_to_float(self, a):
|
||
|
return self.min_value+a*self.step
|
||
|
|
||
|
def _value_handler(self):
|
||
|
self.slider_value = self._int_to_float(super().value())
|