Use float for QSlider
我有一个QLineEdit和QSlider,它们在其中相互交互。
例如。 如果我在QLineEdit中设置一个值,则滑块将被更新,或者如果我将其滑动,则它将更新QLineEdit中的值
1 2 3 4 5 6 7 8 9 10 | # 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)) |
无论如何,我可以使用
@dissidia的回答很好。 但是,如果您的应用程序中有很多滑块,或者需要几个不同的比例因子,则可以将QSlider子类化以创建自己的QDoubleSlider。
下面的类基于其他人的工作,但是具有一个额外的功能,如果您链接到QLineEdit或QDoubleSpinBox,则该功能是:valueChanged的一个新信号,称为doubleValueChanged。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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)) |
经过大量发现,这对我有用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 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) |
我修改了bfris的答案,以使用户无法在步骤之间跟踪滑块,如下所示。 该类使用不同的方法来实现浮点数的使用,这意味着不需要指定小数位数。
该类还允许设置和读取在滑块上选择的点的索引。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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) |