我有一个 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
值?
@dissidia 的回答很好。但是,如果您的应用程序中有很多滑块,或者需要多个不同的比例因子,则需要子类化 QSlider 来制作您自己的 QDoubleSlider。
下面的类基于其他人的工作,但如果链接到 QLineEdit 或 QDoubleSpinBox,则有一个额外的功能:一个名为 doubleValueChanged 的 valueChanged 的新信号。
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))
经过大量发现,这对我有用:
# 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 的答案,以便用户无法跟踪步骤之间的滑块,如下所示。该类使用不同的方法来实现浮点数的使用,这意味着不需要指定小数位数。
SetInterval
方法相当于组合 setTickInterval
和 setSingleStep
方法,但也会停止将滑块定位在刻度值之间。
该类还允许设置和读取滑块上所选点的索引。
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)
它需要了解这一点。 self.slider.setSliderPosition(spinbox_value) --> self.slider.setSliderPosition(int(spinbox_value))