How can I kill a single shot QtCore.QTimer in PyQt4?

pyqt, pyqt4, python, python-2.7, timer

Solution

The problem is that `QTimer.singleShot()` does not return a reference to the `QTimer`. I don't know of anyway to get the Timer ID so you can kill it using that method. However, you can instantiate a normal `QTimer` and make it a single-shot timer (this is not what you have done in your code provided, calling `singleShot` on an instance of `QTimer` creates a new `QTimer` which you do not have access to.)

However, all is not lost. You can create a normal `QTimer` and convert it to a single shot timer using `setSingleShot(True)`. This allows you to call the `stop()` method if you wish to abort the timer. See the code example below which does what you require, on a 3 second timeout. You can push the button as many times as you like in rapid succession, and it will print "hello" once, 3 seconds after you stop. If you push it once, wait 4 seconds, and push it again, it will of course print out twice!

Hope that helps!

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *


class MyApp(QWidget):
    def __init__(self,*args,**kwargs):
        QWidget.__init__(self,*args,**kwargs)
        self.current_timer = None
        self.layout = QVBoxLayout(self)
        self.button = QPushButton('start timer')
        self.button.clicked.connect(self.start_timer)
        self.layout.addWidget(self.button)

    def start_timer(self):
        if self.current_timer:
            self.current_timer.stop()
            self.current_timer.deleteLater()
        self.current_timer = QTimer()
        self.current_timer.timeout.connect(self.print_hello)
        self.current_timer.setSingleShot(True)
        self.current_timer.start(3000)

    def print_hello(self):
        print 'hello'


# Create QApplication and QWidget
qapp = QApplication(sys.argv)  
app = MyApp()
app.show()
qapp.exec_()

Problem

So, in my application, I create a single `QtCore.QTimer` object and then call the `singleShot` method on it to evoke a function after say 60 secs. Now, at any given point in time, if I would need to call the `singleShot` method on it again and prevent the previous `singleShot` method from taking effect (that is preventing it from calling the caller passed to it, if the second time the `singleShot` is invoked before the first 60 seconds), what do I need to do? How can I 'kill' the previous `QTimer` and completely forget about it and work only with the current `QTimer`? Can someone help me out with this? Here's just a sample code: ``` def main(): q = QtCore.QTimer() q.singleShot(4000, print_hello) q.killTimer(id) ##how can I get the value of 'id' so that print_hello() is not called before the end of the 4 seconds? def print_hello(): print 'hello' ``` Thanks

Original source