2

我在我的 GUI 应用程序中使用 QSlider,以便在 QSlider 中更改值后执行繁重的任务。我这样做如下。

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

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

但是我无法顺利更改滑块的值,因为每次更改值时都在运行繁重的任务。

我需要的是在值更改后运行繁重的任务,但前提是滑块的值暂时没有变化。

我不知道如何在 python 中做到这一点。任何帮助..?

4

2 回答 2

3

我不是专家,而且我在战斗之后很久才到达,但我也需要这样的东西,而且我对计时器一无所知。它适用于一个滑块,但我需要 3 个。所以我想出了这个解决方案:当按下滑块时,我断开 valueChanged 插槽,当释放滑块时,我重新连接它并抛出一个 valueChanged 信号,比如这 :

    self.sldAZap.valueChanged.connect(self.sliderChanged)
    self.sldAZap.sliderPressed.connect(self.sldDisconnect)
    self.sldAZap.sliderReleased.connect(self.sldReconnect)

def sldDisconnect(self):
    self.sender().valueChanged.disconnect()

def sldReconnect(self):
    self.sender().valueChanged.connect(self.sliderChanged)
    self.sender().valueChanged.emit(self.sender().value())

def sliderChanged(self):
    print(self.sender().objectName() + " : " + str(self.sender().value())

使用这种方案,从鼠标松开到执行代码之间没有延迟,代码只执行一次。

我希望我足够清楚,它可以帮助某人。

于 2018-07-22T20:31:41.850 回答
2

您可以使用startTimer/killTimer来延迟您的任务:

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)

所以,正如你所看到的,每次用户发生变化时我们都会重新启动计时器,所以如果自上次更改heavy_task未运行以来 3000 毫秒未过期,

但无论如何它都会在主线程中运行,因此一段时间内界面会冻结用户,因此您应该使用 QThreadin来避免在执行timerEvent期间不会冻结的界面 。heavy_task

于 2017-04-01T04:08:33.017 回答