【问题标题】:Use float for QSlider对 QSlider 使用浮点数
【发布时间】:2017-08-06 19:39:06
【问题描述】:

我有一个 QLineEdit 和一个 QSlider,它们在其中相互交互。

例如。如果我在 QLineEdit 中设置了一个值,则滑块将被更新,或者如果我将滑块滑过,它将更新 QLineEdit 中的值

# If user change value on the slider
self.timer_slider.valueChanged.connect(self.set_value)
# If user sets a value in the text box instead
self.timer_value.textChanged.connect(self.set_slider)

def set_slider(self, value):
    self.timer_slider.setValue(int(value))

def set_value(self, value):
    self.timer_value.setText(str(value))

无论如何我可以使用float 代替int 值吗?

【问题讨论】:

标签: python pyqt pyqt4 pyqt5 qslider


【解决方案1】:

经过大量发现,这对我有用:

# 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)

【讨论】:

    【解决方案2】:

    @dissidia 的回答很好。但是,如果您的应用程序中有很多滑块,或者如果您需要几个不同的比例因子,则将 QSlider 子类化以制作您自己的 QDoubleSlider 是值得的。

    下面的课程基于其他人的工作,但如果您链接到 QLineEdit 或 QDoubleSpinBox,您会需要一个额外的功能:一个新的 valueChanged 信号,称为 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))
    

    【讨论】:

      【解决方案3】:

      我修改了 bfris 的答案,以便用户无法跟踪步骤之间的滑块,如下所示。该类使用不同的方法来实现浮点数的使用,这意味着不需要指定小数位数。

      SetInterval 方法等价于组合setTickIntervalsetSingleStep 方法,但也会停止将滑块定位在刻度值之间。

      该类还允许设置和读取滑块上所选点的索引。

      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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-04
        • 1970-01-01
        • 1970-01-01
        • 2012-02-11
        • 1970-01-01
        • 2013-05-07
        • 2012-03-09
        • 1970-01-01
        相关资源
        最近更新 更多