取消所有未完成的 QTimer 事件

发布于 2024-10-18 22:17:54 字数 1550 浏览 1 评论 0原文

我正在寻找一种在 pyqt 中设置多个定时函数调用的方法,并在需要时取消所有挂起的调用。

我正在考虑使用 QtCore.QTimer 来设置函数调用,但我不知道有什么好方法来取消这些调用。有什么想法吗?



使用 QtCore.QTimer.singleShot(1000, self.function) 后我似乎找不到任何取消的方法。相反,如果我创建一个 QTimer 对象列表,我可以停止它们,但随后我被迫管理一个计时器对象列表(创建、删除、活动等),这是我想要的避免。

# Setup a timer object.
timer = QtCore.QTimer(self)
timer.timeout.connect(self.function)
timer.setSingleShot(True)
timer.start(1000)

# To stop the timer object at some later point.
timer.stop()

我还可以管理自己的待处理函数调用队列,如果可能的话我也想避免这种情况(为了简单起见)。



这是一些虚拟代码,显示了我正在尝试做的事情:

import sys
from PyQt4 import QtCore

class Test(QtCore.QObject):

    def __init__(self, parent=None):
        QtCore.QObject.__init__(self, parent)
        

    def addDelayedCall(self, time, function):
        # Do something here.
        pass


    def clearPendingCalls(self):
        print('  Clearing pending function calls.')
        # Do something here.


    def setupCalls(self):
        self.addDelayedCall(500, self.dummy)
        self.addDelayedCall(1000, self.dummy)
        self.addDelayedCall(1500, self.dummy)
        self.addDelayedCall(2000, self.dummy)


    def dummy(self):
        print('dummy just got called.')


if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    test = Test(app)

    QtCore.QTimer.singleShot(0, test.setupCalls)
    QtCore.QTimer.singleShot(1250, test.clearPendingCalls)
                   
    QtCore.QTimer.singleShot(5000, app.quit)            
    sys.exit(app.exec_())

I am looking for a way to setup a number of timed function calls in pyqt, with a way to cancel all pending calls when needed.

I was looking at using QtCore.QTimer to setup the function calls, but I don't know of any good way to cancel these calls. Any ideas?

I can't seem to find any way to cancel after using QtCore.QTimer.singleShot(1000, self.function). If instead I create a list of QTimer objects I can stop them, but then I am forced to manage a list of timer objects (creation, deletion, which are active, etc.), which I would like to avoid.

# Setup a timer object.
timer = QtCore.QTimer(self)
timer.timeout.connect(self.function)
timer.setSingleShot(True)
timer.start(1000)

# To stop the timer object at some later point.
timer.stop()

I could also manage my own queue of pending function calls, which I would also like to avoid if possible (for the sake of simplicity).

Here is some dummy code showing the kind of thing I am trying to do:

import sys
from PyQt4 import QtCore

class Test(QtCore.QObject):

    def __init__(self, parent=None):
        QtCore.QObject.__init__(self, parent)
        

    def addDelayedCall(self, time, function):
        # Do something here.
        pass


    def clearPendingCalls(self):
        print('  Clearing pending function calls.')
        # Do something here.


    def setupCalls(self):
        self.addDelayedCall(500, self.dummy)
        self.addDelayedCall(1000, self.dummy)
        self.addDelayedCall(1500, self.dummy)
        self.addDelayedCall(2000, self.dummy)


    def dummy(self):
        print('dummy just got called.')


if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    test = Test(app)

    QtCore.QTimer.singleShot(0, test.setupCalls)
    QtCore.QTimer.singleShot(1250, test.clearPendingCalls)
                   
    QtCore.QTimer.singleShot(5000, app.quit)            
    sys.exit(app.exec_())

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我最亲爱的 2024-10-25 22:17:54

我提出了直接使用 QObject 提供的计时器功能的解决方案。我怀疑有一个更优雅的解决方案,但这可能会满足我的需要。

import sys
from PyQt4 import QtCore


class Test(QtCore.QObject):

    def __init__(self, parent=None):
        QtCore.QObject.__init__(self, parent)

        self.timers = {}


    def timerEvent(self, event):
        function = self.timers.pop(event.timerId())
        self.killTimer(event.timerId())
        function()


    def addDelayedCall(self, time, function):
        timer_id = self.startTimer(time)

        self.timers[timer_id] = function


    def clearPendingCalls(self):
        print('  Clearing pending function calls.')

        while self.timers:
            timer_id, function = self.timers.popitem()
            self.killTimer(timer_id)


    def setupCalls(self):
        self.addDelayedCall(500, self.dummy)
        self.addDelayedCall(1000, self.dummy)
        self.addDelayedCall(1500, self.dummy)
        self.addDelayedCall(2000, self.dummy)


    def dummy(self):
        print('dummy just got called.')




if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    test = Test(app)

    QtCore.QTimer.singleShot(0, test.setupCalls)
    QtCore.QTimer.singleShot(1250, test.clearPendingCalls)

    QtCore.QTimer.singleShot(5000, app.quit)            
    sys.exit(app.exec_())

I have come up with a solution by directly using the timer functionality provided by QObject. I suspect that there is a more elegant solution, but this will probably work for what I need.

import sys
from PyQt4 import QtCore


class Test(QtCore.QObject):

    def __init__(self, parent=None):
        QtCore.QObject.__init__(self, parent)

        self.timers = {}


    def timerEvent(self, event):
        function = self.timers.pop(event.timerId())
        self.killTimer(event.timerId())
        function()


    def addDelayedCall(self, time, function):
        timer_id = self.startTimer(time)

        self.timers[timer_id] = function


    def clearPendingCalls(self):
        print('  Clearing pending function calls.')

        while self.timers:
            timer_id, function = self.timers.popitem()
            self.killTimer(timer_id)


    def setupCalls(self):
        self.addDelayedCall(500, self.dummy)
        self.addDelayedCall(1000, self.dummy)
        self.addDelayedCall(1500, self.dummy)
        self.addDelayedCall(2000, self.dummy)


    def dummy(self):
        print('dummy just got called.')




if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    test = Test(app)

    QtCore.QTimer.singleShot(0, test.setupCalls)
    QtCore.QTimer.singleShot(1250, test.clearPendingCalls)

    QtCore.QTimer.singleShot(5000, app.quit)            
    sys.exit(app.exec_())
不甘平庸 2024-10-25 22:17:54

您可以断开计时器的超时信号,并在需要时重新连接。一旦断开连接,您将停止接收来自计时器的任何呼叫,即使它仍然保持活动状态。下面是一个小示例:

import sys
from PyQt4 import QtGui, QtCore

class MainForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)

        self.button = QtGui.QPushButton("button", self)       
        self.button.resize(100, 30)

        self.connect(self.button, QtCore.SIGNAL('clicked()'), self.on_button_click)

        self.connected = True
        self.timer = QtCore.QTimer(self)
        self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.on_timeout)
        self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.on_timeout_test)
        self.timer.start(1000)

    def on_button_click(self):
        if self.connected:
            self.disconnect(self.timer, QtCore.SIGNAL('timeout()'), self.on_timeout_test)
        else:
            self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.on_timeout_test)
        self.connected = not self.connected

    def on_timeout(self):
        print 'on_timeout'

    def on_timeout_test(self):
        print 'on_timeout_test'

def main():
    app = QtGui.QApplication(sys.argv)
    form = MainForm()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

一旦计时器启动,当您单击 按钮 on_timeout_test 时,on_timeouton_timeout_test 两个插槽都会被调用code> 插槽会断开连接,然后如果再次单击按钮,则会重新连接。

希望这有帮助,问候

you can disconnect from the timer's timeout signal and connect back whenever you need. Once disconnected you stop receiving any calls from the timer even though it still remains active. Below is a small example:

import sys
from PyQt4 import QtGui, QtCore

class MainForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)

        self.button = QtGui.QPushButton("button", self)       
        self.button.resize(100, 30)

        self.connect(self.button, QtCore.SIGNAL('clicked()'), self.on_button_click)

        self.connected = True
        self.timer = QtCore.QTimer(self)
        self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.on_timeout)
        self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.on_timeout_test)
        self.timer.start(1000)

    def on_button_click(self):
        if self.connected:
            self.disconnect(self.timer, QtCore.SIGNAL('timeout()'), self.on_timeout_test)
        else:
            self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.on_timeout_test)
        self.connected = not self.connected

    def on_timeout(self):
        print 'on_timeout'

    def on_timeout_test(self):
        print 'on_timeout_test'

def main():
    app = QtGui.QApplication(sys.argv)
    form = MainForm()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

once timer started both slots on_timeout and on_timeout_test are getting called, when you click the button on_timeout_test slot gets disconnected and then connected back if button is clicked again.

hope this helps, regards

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文