splinecraft
7/3/2017 - 9:44 PM

PyQt - QSlider for float or double values + tests

PyQt - QSlider for float or double values + tests

from unittest import TestCase
from PyQt5.QtWidgets import QSlider
from DoubleSlider import DoubleSlider

class TestDoubleSlider(TestCase):
    def setUp(self):
        self.slider = DoubleSlider()

    def test_if_double_slider_is_subclass_of_QSlider(self):
        self.assertIsInstance(self.slider, QSlider)

    def test_set_float_value(self):
        self.slider.setValue(0.0)
        self.assertAlmostEqual(self.slider.value(), 0.0, delta=0.01)

        self.slider.setValue(0.6)
        self.assertAlmostEqual(self.slider.value(), 0.6, delta=0.01)

    def test_default_min_max_values(self):
        self.assertAlmostEqual(self.slider.minimum(), 0.0, delta=0.001)
        self.assertAlmostEqual(self.slider.maximum(), 1.0, delta=0.001)

    def test_setting_minimum_value_above_maximum_value(self):
        with self.assertRaises(ValueError):
            self.slider.setMinimum(2.0)

    def test_setting_maximum_value_below_minimum_value(self):
        with self.assertRaises(ValueError):
            self.slider.setMaximum(-0.5)

    def test_valid_limits(self):
        self.slider.setMinimum(0.6)
        self.slider.setMaximum(2.3)
        self.assertAlmostEqual(self.slider.minimum(), 0.6, delta=0.001)
        self.assertAlmostEqual(self.slider.maximum(), 2.3, delta=0.001)

        self.slider.setMinimum(-5.0)
        self.slider.setMaximum(-2.0)
        self.assertAlmostEqual(self.slider.minimum(), -5.0, delta=0.001)
        self.assertAlmostEqual(self.slider.maximum(), -2.0, delta=0.001)

    def test_setting_value_below_lower_limit(self):
        self.slider.setMinimum(0.6)
        self.slider.setValue(0.2)
        self.assertAlmostEqual(self.slider.value(), 0.6, delta=0.001)

    def test_setting_value_above_upper_limit(self):
        self.slider.setMaximum(0.6)
        self.slider.setValue(0.9)
        self.assertAlmostEqual(self.slider.value(), 0.6, delta=0.001)

    def test_usual_numbers(self):
        self.slider.setMinimum(0.8)
        self.slider.setMaximum(2.3)
        self.slider.setValue(1.46)
        self.assertAlmostEqual(self.slider.value(), 1.46, delta=0.01)

    def test_negative_range(self):
        self.slider.setMinimum(-5.0)
        self.slider.setMaximum(-1.0)
        self.slider.setValue(-4.4)
        self.assertAlmostEqual(self.slider.value(), -4.4, delta=0.01)

from PyQt5.QtWidgets import QSlider

class DoubleSlider(QSlider):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.decimals = 5
        self._max_int = 10 ** self.decimals

        super().setMinimum(0)
        super().setMaximum(self._max_int)

        self._min_value = 0.0
        self._max_value = 1.0

    @property
    def _value_range(self):
        return self._max_value - self._min_value

    def value(self):
        return float(super().value()) / self._max_int * self._value_range + self._min_value

    def setValue(self, value):
        super().setValue(int((value - self._min_value) / self._value_range * self._max_int))

    def setMinimum(self, value):
        if value > self._max_value:
            raise ValueError("Minimum limit cannot be higher than maximum")

        self._min_value = value
        self.setValue(self.value())

    def setMaximum(self, value):
        if value < self._min_value:
            raise ValueError("Minimum limit cannot be higher than maximum")

        self._max_value = value
        self.setValue(self.value())

    def minimum(self):
        return self._min_value

    def maximum(self):
        return self._max_value