Search code examples
pythonpython-3.xpyqt5qslider

PyQt5: QSlider valueChanged event with delay


I'm using QSlider in my GUI application in order to perform a heavy task after value changed in the QSlider. I'm doing that as follows.

self.slider.valueChanged.connect(self.value_changed)  # Inside __init__() function

def value_changed(self):  # Inside the class
    # Do the heavy task

But I can't change the value of the slider smoothly because the heavy task is running every time I change the value.

What I need is to run the heavy task after the value changed but only if the value of the slider is not changing for a while.

I can't figure out how to do this in python. Any help..?


Solution

  • You can use startTimer/killTimer to delay your task:

    class Foo(QWidget):
        def __init__(self):
            super().__init__()
            self.timer_id = -1
            self.slider = QSlider(self)
            self.slider.setMinimum(0)
            self.slider.setMaximum(100)
            self.slider.valueChanged.connect(self.value_changed)
    
        def timerEvent(self, event):
            self.killTimer(self.timer_id)
            self.timer_id = -1
            heavy_task()
    
        def value_changed(self):
            if self.timer_id != -1:
                self.killTimer(self.timer_id)
    
            self.timer_id = self.startTimer(3000)
    

    so, as can you see we restart timer every time when user something change, so if 3000 millseconds not expires since last change heavy_task not run,

    but any way it will be running in main thread, so for some time interface freeze for user, so you should use QThread in timerEvent to not have interface that not freeze during heavy_task execution.