具有 "arbitrary" 值的 QSlider(来自 list/array)?
QSlider with "arbitrary" values (from list/array)?
我最终得到了这样的 QSlider 子类:
# via
class ListSlider(QSlider):
def __init__(self, vallist, *args, **kwargs):
QSlider.__init__(self, *args, **kwargs)
self.valuelist = vallist
self.listvalue = None # reserved for actual values of list (.value() will be index)
self.setMaximum(len(self.valuelist)-1)
self.valueChanged.connect(self.on_change_value)
self.on_change_value(0)
@pyqtSlot(int)
def on_change_value(self, value):
self.listvalue = self.valuelist[value]
...然后,有类似的东西:
self.my_list_slider = ListSlider([1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048], Qt.Horizontal)
...
self.my_list_slider.valueChanged.connect(self.self.my_list_slider_valuechange)
...
def my_list_slider_valuechange(self):
curval = self.my_list_slider.value()
print("my_list_slider {} {}".format(curval, self.my_list_slider.listvalue))
...我猜它起作用了——因为当我拖动滑块时,我得到了一个打印输出:
my_list_slider 0 1
my_list_slider 1 2
my_list_slider 2 4
my_list_slider 3 8
my_list_slider 4 16
my_list_slider 5 32
my_list_slider 6 64
my_list_slider 7 128
...
...除了,我有点担心必须在滑块中管理两个变量——原来的值现在变成了一个索引;以及我需要的实际值,现在是根据索引从列表中导出的。
所以,我想知道 - QSlider 是否能够以这种方式原生地处理列表(也就是说,我们沿着列表的值滑动,而不仅仅是数字范围)?或者,如果没有,是否有更多 recommended/straightforward 方法来处理具有任意值(即从列表中获取的值)的滑块?
您可以创建一个新信号来发出所选索引及其对应值的信息:
from PyQt5 import QtCore, QtGui, QtWidgets
class ListSlider(QtWidgets.QSlider):
elementChanged = QtCore.pyqtSignal(int, int)
def __init__(self, values=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setMinimum(0)
self._values = []
self.valueChanged.connect(self._on_value_changed)
self.values = values or []
@property
def values(self):
return self._values
@values.setter
def values(self, values):
self._values = values
maximum = max(0, len(self._values) - 1)
self.setMaximum(maximum)
self.setValue(0)
@QtCore.pyqtSlot(int)
def _on_value_changed(self, index):
value = self.values[index]
self.elementChanged.emit(index, value)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = ListSlider(orientation=QtCore.Qt.Horizontal)
w.values = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]
def my_list_slider_valuechange(index, value):
print("my_list_slider {} {}".format(index, value))
w.elementChanged.connect(my_list_slider_valuechange)
w.show()
sys.exit(app.exec_())
我最终得到了这样的 QSlider 子类:
# via
class ListSlider(QSlider):
def __init__(self, vallist, *args, **kwargs):
QSlider.__init__(self, *args, **kwargs)
self.valuelist = vallist
self.listvalue = None # reserved for actual values of list (.value() will be index)
self.setMaximum(len(self.valuelist)-1)
self.valueChanged.connect(self.on_change_value)
self.on_change_value(0)
@pyqtSlot(int)
def on_change_value(self, value):
self.listvalue = self.valuelist[value]
...然后,有类似的东西:
self.my_list_slider = ListSlider([1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048], Qt.Horizontal)
...
self.my_list_slider.valueChanged.connect(self.self.my_list_slider_valuechange)
...
def my_list_slider_valuechange(self):
curval = self.my_list_slider.value()
print("my_list_slider {} {}".format(curval, self.my_list_slider.listvalue))
...我猜它起作用了——因为当我拖动滑块时,我得到了一个打印输出:
my_list_slider 0 1
my_list_slider 1 2
my_list_slider 2 4
my_list_slider 3 8
my_list_slider 4 16
my_list_slider 5 32
my_list_slider 6 64
my_list_slider 7 128
...
...除了,我有点担心必须在滑块中管理两个变量——原来的值现在变成了一个索引;以及我需要的实际值,现在是根据索引从列表中导出的。
所以,我想知道 - QSlider 是否能够以这种方式原生地处理列表(也就是说,我们沿着列表的值滑动,而不仅仅是数字范围)?或者,如果没有,是否有更多 recommended/straightforward 方法来处理具有任意值(即从列表中获取的值)的滑块?
您可以创建一个新信号来发出所选索引及其对应值的信息:
from PyQt5 import QtCore, QtGui, QtWidgets
class ListSlider(QtWidgets.QSlider):
elementChanged = QtCore.pyqtSignal(int, int)
def __init__(self, values=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setMinimum(0)
self._values = []
self.valueChanged.connect(self._on_value_changed)
self.values = values or []
@property
def values(self):
return self._values
@values.setter
def values(self, values):
self._values = values
maximum = max(0, len(self._values) - 1)
self.setMaximum(maximum)
self.setValue(0)
@QtCore.pyqtSlot(int)
def _on_value_changed(self, index):
value = self.values[index]
self.elementChanged.emit(index, value)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = ListSlider(orientation=QtCore.Qt.Horizontal)
w.values = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]
def my_list_slider_valuechange(index, value):
print("my_list_slider {} {}".format(index, value))
w.elementChanged.connect(my_list_slider_valuechange)
w.show()
sys.exit(app.exec_())