Fayad
Fayad

Reputation: 120

PyQt Slider does not move to position of setValue

I have a QSlider that I want to set it's value programmatically overtime not just initially. The issue is that when I set the value of the slider after I move it, the slider position does not move to the correct value position, but the value does change.

This is the code to reproduce the issue (I am running this on an M1 Mac):

from PyQt5.QtWidgets import (QWidget, QSlider, QHBoxLayout,
                             QLabel, QApplication, QPushButton)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
import sys


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        hbox = QHBoxLayout()

        sld = QSlider(Qt.Horizontal, self)
        sld.setRange(0, 100)

        sld.valueChanged.connect(self.updateLabel)

        self.label = QLabel('0', self)
        self.label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
        self.label.setMinimumWidth(80)

        button = QPushButton('Move to 12', self)
        button.pressed.connect(lambda: sld.setValue(12))

        hbox.addWidget(sld)
        hbox.addSpacing(15)
        hbox.addWidget(self.label)
        hbox.addSpacing(15)
        hbox.addWidget(button)

        self.setLayout(hbox)

        self.setGeometry(300, 300, 350, 250)
        self.setWindowTitle('QSlider')
        self.show()

    def updateLabel(self, value):

        self.label.setText(str(value))


def main():

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

Upvotes: 5

Views: 3197

Answers (1)

StarShine
StarShine

Reputation: 2060

I had the same problem. I added a helper function to make sure that the position of the handle is updated, and then invoke a repaint of the component. This seems to work well. I also set 'tracking' to enabled, but this may not necessarily be needed.

def helperSetSliderIntValue(self, slider, x):
        slider.tracking = True
        slider.value = int(x)
        slider.sliderPosition = int(x)
        slider.update()
        slider.repaint()

After you've set the range to allow for a valid int value, you would then simply call it like:

myIntValue = 15
self.mySliderComponent.setRange(0,16)
self.helperSetSliderIntValue(self.mySliderComponent, myIntValue )

Maybe someone with a little time to spare can wrap this in a fix for QSlider widget in c++ and commit the fix to PyQt.

Upvotes: 1

Related Questions