3

I am developing an app in python with pyGtk+Glade.

I want to execute a function every N seconds (just like in javascript the function setTimeout()). If the user perform a click, some action must be done, and the timer must be reset.

I was trying with threading.Timer, something like this:

def callback():
    print "callback executed"

t = threading.Timer(10.0, callback)
t.start()

but it doesn't work for me because it blocks everything for the N secs and doesn't capture the user click.

Any other option?

1
  • Perhaps if you placed created a new thread and in that thread set up the timer you might have more success? That way when it is blocking it can yield to main and your program execution can continue along it's merry way. Commented Feb 9, 2012 at 2:47

2 Answers 2

2

Since you're using PyGTK, your program should probably be using the g_main_loop, in which case you can call glib.timeout_add (interval, callback) to add a callback that gets called (roughly) every X seconds.

Here's an example:

import glib
import gtk

def yo ():
    print "yo"
    return True

glib.timeout_add (1000, yo)
gtk.main ()

Unfortunately, to reset the timeout I couldn't come up with an elegant solution. But you can create your own main loop so you have control over when the timeout resets, sorta like this:

import glib
import gtk
import time

timeout = 1;
timer = time.time() + timeout
while (True):
    gtk.main_iteration (False)
    if (timer <= time.time()):
        print "Time up!"
        timer = time.time() + timeout
Sign up to request clarification or add additional context in comments.

3 Comments

Actually I started working with timeout_add. It worked fine, but I could not achieve the part of reseting the timer when the user makes a click. Could you give some advice with that?
Thanks for your help. I solved it by removing/adding the timer, using the gobject.remove_source(timer_id) and then gobject.timeout_add(TIME, FUNC)
timeout_add can NOT be used for long periods (like an hour or more) because if you suspend your computer, the timer is gonna be screwed up.
0

This creates a timer which calls MainWin.update() every second. When the button is pressed, the current timer is killed and a new timer is started.

import pygtk
pygtk.require('2.0')
import gtk
import gobject
import time

class MainWin(object):
    def destroy(self, widget, data=None):
        gtk.main_quit()
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("destroy", self.destroy)
        self.window.set_border_width(10)
        self.button = gtk.Button("Reset")
        self.button.connect("clicked", self.onclick)
        self.window.add(self.button)
        self.button.show()
        self.window.show()
        self.reset_timer = False
        self.count = 0
        self.duration = 1000
        self.timer = gobject.timeout_add(self.duration, self.update)
    def reset(self):
        print('Resetting timer')
        gobject.source_remove(self.timer)
        # start a new period call to update
        self.count = 0        
        self.timer = gobject.timeout_add(self.duration, self.update) 
    def onclick(self, widget):
        # Every action which resets the timer should call self.reset_timer().
        self.reset()
    def update(self):
        print('{t:.1f}: count = {i}'.format(t=time.time() % 100, i=self.count))
        self.count += 1
        return True
    def main(self):
        gtk.main()

if __name__=='__main__':
    MainWin().main()

1 Comment

timeout_add does not work properly with suspend. and threading.Timer does not seem to work properly with PyGtk either. I'm still not sure how to set long-duration timers/scheduling in PyGtk...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.