Skip to main content

Ralsina.Me — Roberto Alsina's website

PyQt Quickie: QTimer

QTimer is a fair­ly sim­ple class: you use it when you want some­thing to hap­pen "in a while" or "ev­ery once in a while".

The first case is some­thing like this:

# call f() in 3 seconds
QTimer.singleShot(3000, f)

The sec­ond is this:

# Create a QTimer
timer = QTimer()
# Connect it to f
timer.timeout.connect(f)
# Call f() every 5 seconds
timer.start(5000)

Sim­ple, right? Well, yes, but it has some trick­s.

  1. You have to keep a re­f­er­ence to``­­timer``

    If you don't, it will­get garbage-­­col­lec­t­ed, and f() will nev­er be called.

  2. It may not call f() in 5 sec­ond­s.

    It will call f() more or less 5 sec­onds af­ter you en­ter the event loop. That may not be quick­ly af­ter you start the timer at al­l!

  3. You may get over­lap­ping cal­l­s.

    If f() takes long to fin­ish and re-en­ters the event loop (for ex­am­ple, by call­ing pro­ces­sEv­ents) maybe the timer will time­out and call it again be­fore it's fin­ished. That's al­most nev­er a good thing.

So, you can do this:

def f():
    try:
        # Do things
    finally:
        QTimer.singleShot(5000, f)

f()

What that snippet does, is, calls f() only once. But f itself schedules itself to run in 5 seconds. Since it does it in a finally, it will do so even if things break.

That means no overlapping calls. It also means it won't be called every 5 seconds, but 5 seconds plus whatever f takes to run. Also, no need to keep any reference to a QTimer.

Fi­nal tip: You can al­so use QTimer to do some­thing "as soon as you are in the event loop"

QTimer.singleShot(0, f)

Hope it was use­ful!

Asdrúbal Iván Suárez Rivera / 2012-02-16 20:05:

Gracias! Me ha servido de mucho!

asdassdafasdfasd a / 2012-11-16 14:01:

Very helpful and simple tutorial. Thank You!


Contents © 2000-2023 Roberto Alsina