QSlider stepping?

Question:

I’d like to specify the steps that a QSlider can slide, like it is possible for the QSpinBox by using setSingleStep. I tried to use setSingleStep of QAbstractSlider, but this seems to have no effect.

Any ideas?

Asked By: Richard Durr

||

Answers:

Try setting the tickInterval

EDIT

Sorry for the tickInterval, didn’t quite thinked about it, however i have this working code and it does what you want using setSingleStep

import sys
from PyQt4.QtGui import QApplication, QSlider, QMainWindow

class Window(QMainWindow):
    def __init__(self, parent = None):
        super(Window, self).__init__(parent)

        slider = QSlider()
        slider.setMinimum(0)
        slider.setMaximum(100)

        slider.setTickInterval(20)
        slider.setSingleStep(20)


        self.setCentralWidget(slider)


if __name__ == "__main__":
    app = QApplication(sys.argv)

    window = Window()
    window.show()

    sys.exit(app.exec_())
Answered By: armonge

I extended the QSlider class to limit the user so that they cannot track the slider between the steps.
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 use of float values as slider limits or intervals and 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)
Answered By: Siyh

setSingleStep() still don’t work on slider in PyQt5 now

so I tried this to make the same effect

your_slider = QtWidgets.QSlider()
your_slider.valueChanged.connect(lambda:set_step(step))
flag = 0
def your_func():
    pass
    #func here
def set_step(step):
    value = your_slider.value()//step*step
    your_slider.setValue(value)
    if flag != value:
        flag = value
        your_func()
    

I just learned python for several months

Please correct it if there is a mistake

Answered By: jiahao.d

My solution is using signal sliderMoved and correct the position. The below example moves slider to value 50 or 100

import sys
from PyQt5.QtGui import QApplication, QSlider, QMainWindow

class Window(QMainWindow):
    def __init__(self, parent = None):
        super(Window, self).__init__(parent)

        self.slider = QSlider(self)
        self.slider.setMinimum(0)
        self.slider.setMaximum(100)

        self.slider.setTickInterval(20)
        self.slider.setSingleStep(20)

        self.slider.sliderMoved.connect(self.correct_pos)    

        self.setCentralWidget(self.slider)
     
    def correct_pos(self, pos):
        if pos < 50:
            corrected = 50
        else:
            corrected = 100
        self.slider.setValue(corrected)


if __name__ == "__main__":
    app = QApplication(sys.argv)

    window = Window()
    window.show()

    sys.exit(app.exec_())
Answered By: LiberiFatali