Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Slider anomaly



  • I stumbled on an anomaly with slider. If it is a consequence of something I am doing wrong, I would like to know what it is before my ignorance propagates to more code. Here is a test program:

    import sys
    
    from PySide2.QtCore import QTimer
    from PySide2.QtWidgets import QApplication, QWidget, QStackedWidget, QPushButton
    from PySide2.QtWidgets import QLabel, QHBoxLayout, QSlider
    from PySide2.QtGui import Qt
    
    class Tester(QWidget):
        def __init__(self):
            super().__init__()
            self.timer = None
    
            self.slider = QSlider()
            self.button = QPushButton()
            self.stacked_widget = QStackedWidget()
            self.label = QLabel("Push the button")
    
            self.slider.setOrientation(Qt.Horizontal)
            self.button.setCheckable(True)
    
            self.button.clicked.connect(self.on_button_clicked)
            self.slider.valueChanged.connect(self.on_volume_slider_valueChanged)
    
            self.stacked_widget.addWidget(self.label)
            if (int(sys.argv[1])):
                self.page_2_widget = QWidget()
                self.page_2_layout = QHBoxLayout()
                self.page_2_layout.addWidget(self.slider)
                self.page_2_widget.setLayout(self.page_2_layout)
                self.stacked_widget.addWidget(self.page_2_widget)
            else:
                self.stacked_widget.addWidget(self.slider)
    
            self.hbox = QHBoxLayout()
            self.hbox.addWidget(self.stacked_widget)
            self.hbox.addWidget(self.button)
    
            self.setLayout(self.hbox)
    
        def on_button_clicked(self, checked):
            self.stacked_widget.setCurrentIndex(int(checked))
            if checked:
                self.timer = self.get_timer()
                self.timer.start()
            else:
                self.timer.stop()
    
        def on_volume_slider_valueChanged(self, value):
            print(f"slider value = {value}")
            if self.timer is not None:
                self.timer.start() # restart timer as long as slider in use
    
        def get_timer(self):
            def timeout_cb():
                self.stacked_widget.setCurrentIndex(0)
                self.button.setChecked(0)
                self.slider.setSliderDown(False)
            timer = QTimer()
            timer.setSingleShot(True)
            timer.setInterval(3000)
            timer.timeout.connect(timeout_cb)
            return timer
    
    
    if __name__ == "__main__":
        app = QApplication()
        tester = Tester()
        tester.show()
        app.exec_()
    
    

    Save it to test.py and run the program with the command

    python test.py 1
    

    Note when you click on the button that a slider appears. If you do nothing, it will disappear after 3 seconds. Click on the slider and drag the handle. You will see that the value changes. Continue to hold the handle (mouse button down), but stop moving. After 3 seconds, the slider disappears. Now, still holding the mouse button down, move the pointer. You will see that the value changes even though the slider disappeared. If you run the program using

    python test.py 0
    

    the value will not change after the slider disappears. That behavior is what I expect. The difference between the two modes of operation is that I put the slider directly on the second page of the stacked widget in the case that works, but it is in a widget in the case that does not. Is there something wrong with the way I implemented the latter that is responsible for this anomaly?



  • Cannot speak to it being an anomoly but the workaround is to setEnabled(False) on the slider when it is hidden, and setEnabled(True) when it is shown.

    I suspect that disabling the slider is required to flush the mouse button hold.

    Also, I don't care to jump thru the hoops to install pyside at 3AM so I changed your imports to use PyQt5 and the behaviour was as you described.



  • Thanks for the suggestion. I tried setSliderDown, but it had no effect. It is possible that this method does not do what I guessed it does as there is no documentation. I assumed it controls whether the slider "button" is down. However, the slider still moved even when isSliderDown was False. Anyway, your workaround is easy, so I will use it.


Log in to reply