matrixinverter
matrixinverter

Reputation: 1

QSlider handle does not move programmatically after moving the handle manually

I have a slider that can be controlled by rewind/forward buttons or manually. When I start the application, clicking the buttons works fine and the slider moves as desired. However, if I drag the slider handle to a given position, the buttons still trigger the valueChanged event but the position of the handle is not updated on the screen. I noticed that if I double click the handle, the handle starts to move again according to the buttons.

I could overcome this problem by simulating a mouse click (with QMouseEvent), but it seems a bit of a hack and maybe there's a better solution I could not figure out.

Here's my code:

from PyQt5.QtWidgets import QSlider, QHBoxLayout, QLabel, QWidget, QToolButton
from PyQt5.Qt import Qt, QStyle


class TimeSliderWidget(QWidget):

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

        self._createWidgets()
        self._configureLayout()

    def setTimeSteps(self, timeSteps: int):
        self._timeSlider.setRange(0, timeSteps - 1)

    def reset(self):
        self._timeSlider.setValue(0)

    def setEnabled(self, enabled: bool):
        self._timeSlider.setEnabled(enabled)
        if enabled:
            self._updateButtonsState(self._timeSlider.value())
        else:
            self._rewindButton.setEnabled(False)
            self._forwardButton.setEnabled(False)

    def value(self):
        return self._timeSlider.value()

    def _createWidgets(self):
        self._timerLabel = QLabel("0")
        self._timeSlider = QSlider(Qt.Horizontal)
        self._timeSlider.setSingleStep(1)
        self._timeSlider.valueChanged.connect(self._onValueChange)
        self._rewindButton = QToolButton()
        self._rewindButton.setIcon(self.style().standardIcon(QStyle.SP_MediaSeekBackward))
        self._forwardButton = QToolButton()
        self._forwardButton.setIcon(self.style().standardIcon(QStyle.SP_MediaSeekForward))
        self._rewindButton.clicked.connect(self._onRewindClick)
        self._forwardButton.clicked.connect(self._onForwardClick)

    def _configureLayout(self):
        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._rewindButton)
        layout.addWidget(self._forwardButton)
        layout.addWidget(self._timeSlider)
        layout.addWidget(self._timerLabel)

    def _onValueChange(self, newValue: int):
        self._updateTimerLabel(newValue)

    def _onRewindClick(self):
        self._timeSlider.triggerAction(QSlider.SliderSingleStepSub)

    def _onForwardClick(self):
        self._timeSlider.triggerAction(QSlider.SliderSingleStepAdd)

    def _updateTimerLabel(self, timeStep: int):
        self._timerLabel.setText(f"{timeStep}")


if __name__ == '__main__':
    app = QApplication([])
    slider = TimeSliderWidget()
    slider.setTimeSteps(20)
    window = QMainWindow()
    window.setCentralWidget(slider)
    window.show()
    app.exec()

I also tried setValue, setSliderPosition instead of triggerAction but none of these worked.

Handle in the correct position after clicking the buttons

Handle in the correct position after clicking the buttons

Handle not moving after clicking buttons

Handle not moving after clicking buttons

Upvotes: 0

Views: 336

Answers (0)

Related Questions