python中的非阻塞计时器

时间:2012-02-09 02:41:40

标签: python

我正在使用pyGtk + Glade在python中开发一个应用程序。

我想每N秒执行一次函数(就像在javascript中的函数setTimeout())。如果用户执行单击,则必须执行某些操作,并且必须重置计时器。

我正在尝试threading.Timer,类似这样:

def callback():
    print "callback executed"

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

但它对我不起作用,因为它会阻止N秒的所有内容,并且不会捕获用户点击。

还有其他选择吗?

2 个答案:

答案 0 :(得分:2)

由于你正在使用PyGTK,你的程序可能应该使用g_main_loop,在这种情况下你可以调用glib.timeout_add(interval,callback)来添加一个每隔X秒被调用一次的回调。

以下是一个例子:

import glib
import gtk

def yo ():
    print "yo"
    return True

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

不幸的是,要重置超时,我无法想出一个优雅的解决方案。但是你可以创建自己的主循环,这样你就可以控制超时重置的时间,如下所示:

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

答案 1 :(得分:0)

这会创建一个每秒调用MainWin.update()的计时器。按下按钮时,将终止当前计时器并启动新计时器。

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()