Use float for QSlider

前端 未结 3 1020
轻奢々
轻奢々 2021-01-07 01:05

I have a QLineEdit and a QSlider in which it interacts with each other.

Eg. If I set a value in the QLineEdit, the slider will be updated, or if I slide the slider a

相关标签:
3条回答
  • 2021-01-07 01:19

    I modified bfris's answer so that the user cannot track the slider between the steps as shown below. The class uses a different method to implement the use of floats, which means that the number of decimal places doesn't need to be specified.

    The SetInterval method is equivalent to combining the setTickInterval and setSingleStep methods, but also stops the slider being positioned between tick values.

    The class also allows the index of the point selected on the slider to be set and read.

    class DoubleSlider(qw.QSlider):
    
        def __init__(self, *args, **kargs):
            super(DoubleSlider, self).__init__( *args, **kargs)
            self._min = 0
            self._max = 99
            self.interval = 1
    
        def setValue(self, value):
            index = round((value - self._min) / self.interval)
            return super(DoubleSlider, self).setValue(index)
    
        def value(self):
            return self.index * self.interval + self._min
    
        @property
        def index(self):
            return super(DoubleSlider, self).value()
    
        def setIndex(self, index):
            return super(DoubleSlider, self).setValue(index)
    
        def setMinimum(self, value):
            self._min = value
            self._range_adjusted()
    
        def setMaximum(self, value):
            self._max = value
            self._range_adjusted()
    
        def setInterval(self, value):
            # To avoid division by zero
            if not value:
                raise ValueError('Interval of zero specified')
            self.interval = value
            self._range_adjusted()
    
        def _range_adjusted(self):
            number_of_steps = int((self._max - self._min) / self.interval)
            super(DoubleSlider, self).setMaximum(number_of_steps)
    
    0 讨论(0)
  • 2021-01-07 01:22

    @dissidia's answer is good. But if you have a lot of sliders in your app or if you need several different scale factors, it pays to subclass QSlider to make your own QDoubleSlider.

    The class below is based on the work of others, but has an extra feature you'll want if you link to a QLineEdit or QDoubleSpinBox: a new signal for valueChanged called doubleValueChanged.

    class DoubleSlider(QSlider):
    
        # create our our signal that we can connect to if necessary
        doubleValueChanged = pyqtSignal(float)
    
        def __init__(self, decimals=3, *args, **kargs):
            super(DoubleSlider, self).__init__( *args, **kargs)
            self._multi = 10 ** decimals
    
            self.valueChanged.connect(self.emitDoubleValueChanged)
    
        def emitDoubleValueChanged(self):
            value = float(super(DoubleSlider, self).value())/self._multi
            self.doubleValueChanged.emit(value)
    
        def value(self):
            return float(super(DoubleSlider, self).value()) / self._multi
    
        def setMinimum(self, value):
            return super(DoubleSlider, self).setMinimum(value * self._multi)
    
        def setMaximum(self, value):
            return super(DoubleSlider, self).setMaximum(value * self._multi)
    
        def setSingleStep(self, value):
            return super(DoubleSlider, self).setSingleStep(value * self._multi)
    
        def singleStep(self):
            return float(super(DoubleSlider, self).singleStep()) / self._multi
    
        def setValue(self, value):
            super(DoubleSlider, self).setValue(int(value * self._multi))
    
    0 讨论(0)
  • 2021-01-07 01:30

    After much findings, this works for me:

    # Connection Signals
    
    # When user tweaks using the slider
    self.slider.valueChanged[int].connect(self.update_spinbox)
    # When user modify via the spinbox
    self.spinbox_value.editingFinished.connect(self.update_slider)
    
    
    # Functions for each modication made towards slider and spinbox
    def update_slider(self):
        # spinbox_value uses float/ doubles type
        # '*100' is used to convert it into integer as QSlider
        # only register integer type
        spinbox_value = self.spinbox_value.value() * 100
        self.slider.setSliderPosition(spinbox_value)
    
    def update_spinbox(self, value):
        # QSlider only uses integer type
        # Need to convert the value from integer into float
        # and divides it by 100
        self.spinbox_value.setValue(float(value) / 100)
    
    0 讨论(0)
提交回复
热议问题