4

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()

Fayad
  • 110
  • 11
  • 1
    Seems related to [qtbug-98093](https://bugreports.qt.io/browse/QTBUG-98093) (introduced with the latest macOS update), solved for Qt6, but there's no certainty about the Qt5 fix. Yet another macOS annoying inconsistency. – musicamante Mar 16 '22 at 20:53
  • try change to `button.pressed.connect(lambda: (sld.setValue(12), sld.repaint()))` – eyllanesc Mar 16 '22 at 20:55
  • @eyllanesc That did not work, still the same behaviour – Fayad Mar 16 '22 at 21:10
  • @Fayad did you ever get this to work? I'm having a similar issue with multiple sliders in one layout – user3711502 Jun 29 '22 at 18:56
  • Unfortunately not, it is a know bug that has been reported and it was closed with no fix. Here is the link to the issue https://bugreports.qt.io/browse/QTBUG-98093 – Fayad Jun 30 '22 at 19:32

1 Answers1

0

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.

StarShine
  • 1,940
  • 1
  • 27
  • 45
  • Using update and repaint like this does not work for me in PyQt5 – ToddP Feb 18 '23 at 03:44
  • I'm also using PyQT5. are you sure you are passing ints and not something else? I remember it was quite picky about the type. – StarShine Feb 22 '23 at 10:28
  • 100% certain that ints are used. This is apparently a bug in macos: https://bugreports.qt.io/browse/QTBUG-98093 – ToddP Feb 23 '23 at 19:15