示例Python定时器程序

1 投票
2 回答
806 浏览
提问于 2025-04-18 18:33

我正在尝试在Tkinter中做一个计时器功能,想要在计时事件中连续调用一个方法。

我的程序是一个简单的子类,没有包含根窗口或主窗口,因为我把主类分开了,所以我在写after函数时遇到了困难。请问没有根窗口的情况下能写after函数吗?因为调用tk会显示一个不需要的tk窗口,我只想在我的Python命令行中看到计时器事件的输出,这样可以吗?

class App():

    def __init__ (self): 

        self.timer_count = 0

        for Test in range(4):
           self.update_clock()


    def update_clock(self):

        self.timer_count+= 1
        print self.timer_count

        self.after(100, self.execute)  # Is it possible?
        #                                Can timer work without any root instance?
        #
        #self.root.after(100, self.update_clock)


App_Obj = App()

2 个回答

0

在编程中,有时候我们需要让程序在特定的条件下执行某些操作。比如说,当一个按钮被点击时,程序就要做一些事情。这个过程就叫做“事件处理”。

事件处理的基本思路是:我们先定义一个“事件”,然后告诉程序当这个事件发生时应该执行什么。这样,程序就能根据用户的操作来做出反应。

举个例子,想象一下你在玩一个游戏,按下“开始”按钮后,游戏就开始了。这里的“开始”按钮就是一个事件,而游戏开始的动作就是事件处理的结果。

在编程中,我们通常会使用一些特定的代码来设置这些事件和处理方式。这样,当用户进行某个操作时,程序就会自动执行我们预设的代码。

总之,事件处理就是让程序能够根据用户的操作来做出反应的一种方式,帮助我们创建更互动的应用。

import time

time.clock() #To start timing

#Your code here

timing = time.clock() #Returns a float ex. 0.05
                      #this is the time from start to finish in ms
0

Tkinter可以做的事情,但要记住,调度的方式有所不同

Tkinter是一个以图形用户界面为主的框架,里面有很多强大的功能。

( Python本身允许你独立于Tkinter来设计东西。)

Tkinter中的基于时间的事件可以设置,但正如上面所说,用户对定时器的控制是被避免的(没有合理的近实时系统会允许用户去干扰,甚至阻塞,代码执行的流程……)

所以,Tkinter的调度工具基本上就是这些:

aTkScheduledEVENTid = <aTkRootWidget>.after( msecsAfter, aFun2Bcalled = None, *args )
# use
# for deterministic / set wait-time

aTkDeferredEVENTid  = <aTkRootWidget>.after_idle( aFun2Bcalled = None, *args )
# use
# for non-deterministic / deferred till <SIG_IDLE> state of the GUI control-loop

<aTkRootWidget>.after_cancel( { aTkScheduledEVENTid | aTkDeferredEVENTid } )
# use
# upon a need to **cancel**/re-schedule a set execution

单次调用的魔法

一个定时的函数调用只会执行一次,因此在被调用的函数内部再次安排这个任务是很常见的,这样可以重新注册下一个基于时间的函数调用。

Arthur在上面分享了一个链接,里面有Bryan Oakley的一个很不错的代码片段。

添加一个小技巧可以帮助你在实际负载下更好地理解Tkinter的时间管理

( 有些平台在[毫秒]-级别下不显示时间分辨率 )

class App():                            # Bryan Oakley, in http://stackoverflow.com/a/2401181/3666197
    def __init__( self ):
        self.root = tk.Tk()
        self.label = tk.Label( text = "init" )
        self.label.pack()
        self.update_clock()             # inital call to set a scheduled execution
        self.root.lower()               # OP.Edit: hide the Tk-window, as wanted
        self.root.mainloop()

    def update_clock( self ):
        # \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
        #
        # DEMO to show real plasticity of the Tkinter scheduler timing(s)
        #
        print time.time()               # show real activation timestamp w [msecs]
        #
        # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
        now = time.strftime( "%H:%M:%S" )
        self.label.configure( text = now )
        self.root.after( 1000,         # re-instate next scheduled call, theoretically after given delay
                         self.update_clock
                         )

撰写回答