tkinter:模拟时钟刷新-如何在“之后”进行更新。功能工作? [英] tkinter: Analog clock refreshing - how does "after" function work?

查看:225
本文介绍了tkinter:模拟时钟刷新-如何在“之后”进行更新。功能工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我是python的新手,并且在Tkinter上编写了一个模拟时钟,该时钟可以每秒显示一次。但是此时钟使用 while 1 无限循环刷新时间,这完全阻塞了程序的其余部分。因为我想在另一个程序中使用它作为并行函数,所以我不得不对刷新方法进行重新编程。

Recently, I'm beginner in python, and I've programmed an analog clock on Tkinter, which can display time every second. But this clock uses a while 1 infinite loop to refresh the time, that totally blocks the rest of the program. Because I want to use it in an another program, as a parallel function, I had to reprogram the refreshing method.

我找到了关于<$ c $的一些信息c> after()函数可以(我认为)对我有帮助,但是我得到了 RuntimeError:在比较中超出了最大递归深度,我没有不明白为什么。我的时钟图对于python来说太重了吗?我将代码放在这里,希望有人能理解我的问题并能为我提供帮助。

I've found something about the after() function which can (I think) help me, but I get a RuntimeError: maximum recursion depth exceeded in comparison and I don't understand why. Is the drawing of my clock too heavy for python? I'll put the code here and hope someone understand my problem and can help me.

(PS 1:原则功能之前,我不关心代码而且我不认为问题出在那儿,但是我仍然会发布它,因为我完全不确定这部分是否已调试。

(PS 1: I don't take care about the code before "principle function" and I don't think the problem is there, but I'll still post it because I'm not sure at all that this part is debugged.

PS 2 :我真的很抱歉我的英语(这可能是个问题),所以请告诉我您是否听不懂。)

PS 2: I'm really sorry about my English which may be a problem, so tell me if you don't understand.)

#list of imported modules
from tkinter import *
from math import cos, sin
from time import gmtime, sleep

#defining of secondary functions

def drawcircle(Alpha,Beta,Rayon,Couleur,can): #draw a circle base on center coord radius and color
    x1,y1,x2,y2=Alpha-Rayon, Beta-Rayon, Alpha+Rayon, Beta+Rayon
    can.create_oval(x1,y1,x2,y2,fill=Couleur)

def drawPetAig(CoordA, CoordZ, Taille, Omega, can): #function to drawn the second hand of the clock
    Pi = 3.141592
    Omega = ((Omega/60)+1)*30
    can.create_line(CoordA + (Taille/3) * cos(Pi*(Omega/180)), CoordZ + (Taille/3) * sin(Pi*(Omega/180)), CoordA - (Taille/8) * cos(Pi*(Omega/180)), CoordZ - (Taille/8) * sin(Pi*(Omega/180)) )

def drawGrdAig(CoordA, CoordZ, Taille, Omega, can): #function to draw the minute hand, based on center coord and minutes.
    Pi = 3.141592
    Omega = (Omega-15)*6
    can.create_line(CoordA + (Taille/1.5) * cos(Pi*(Omega/180)), CoordZ + (Taille/1.5) * sin(Pi*(Omega/180)), CoordA - (Taille/6) * cos(Pi*(Omega/180)), CoordZ - (Taille/6) * sin(Pi*(Omega/180)))

def drawSecAig(CoordA, CoordZ, Taille, Omega, can): #function to draw the hour hand
    Pi = 3.141592
    Omega = (Omega-15) *6
    can.create_line(CoordA + (Taille/1.5) * cos(Pi*(Omega/180)), CoordZ + (Taille/1.5) * sin(Pi*(Omega/180)), CoordA - (Taille/6) * cos(Pi*(Omega/180)), CoordZ - (Taille/6) * sin(Pi*(Omega/180)), fill = "red")

def fondhorloge(CoordA, CoordZ, Taille, can1):  #function drawing the backgroud of the clock
    Pi = 3.141592
    drawcircle(CoordA, CoordZ, Taille + (Taille/10), "grey6",can1) #drawing the surrounding of the clock
    drawcircle(CoordA, CoordZ, Taille, "ivory3",can1)#backgroud
    drawcircle(CoordA, CoordZ, Taille/80, "grey6",can1)#central point/needle articulation
    can1.create_line(CoordA + (Taille - (Taille/15)), CoordZ, CoordA + (Taille - (Taille/5)), CoordZ) #drawing the N/S/E/W decorativ hour position
    can1.create_line(CoordA, CoordZ + (Taille - (Taille/15)), CoordA, CoordZ + (Taille - (Taille/5)))
    can1.create_line(CoordA - (Taille - (Taille/15)), CoordZ, CoordA - (Taille - (Taille/5)), CoordZ)
    can1.create_line(CoordA, CoordZ - (Taille - (Taille/15)), CoordA, CoordZ - (Taille - (Taille/5)))

    #here, this 4*2 line defined the position of the 8 intermediate line between the N/S/E/W decorativ line.
    can1.create_line(CoordA + (Taille/1.05) * cos(Pi*(30/180)), CoordZ + (Taille/1.05) * sin(Pi*(30/180)), CoordA + (Taille/1.20) * cos(Pi*(30/180)), CoordZ + (Taille/1.20) * sin(Pi*(30/180)))
    can1.create_line(CoordA + (Taille/1.05) * cos(Pi*(60/180)), CoordZ + (Taille/1.05) * sin(Pi*(60/180)), CoordA + (Taille/1.20) * cos(Pi*(60/180)), CoordZ + (Taille/1.20) * sin(Pi*(60/180)))

    can1.create_line(CoordA - (Taille/1.05) * cos(Pi*(30/180)), CoordZ - (Taille/1.05) * sin(Pi*(30/180)), CoordA - (Taille/1.20) * cos(Pi*(30/180)), CoordZ - (Taille/1.20) * sin(Pi*(30/180)))
    can1.create_line(CoordA - (Taille/1.05) * cos(Pi*(60/180)), CoordZ - (Taille/1.05) * sin(Pi*(60/180)), CoordA - (Taille/1.20) * cos(Pi*(60/180)), CoordZ - (Taille/1.20) * sin(Pi*(60/180)))

    can1.create_line(CoordA + (Taille/1.05) * cos(Pi*(30/180)), CoordZ - (Taille/1.05) * sin(Pi*(30/180)), CoordA + (Taille/1.20) * cos(Pi*(30/180)), CoordZ - (Taille/1.20) * sin(Pi*(30/180)))
    can1.create_line(CoordA + (Taille/1.05) * cos(Pi*(60/180)), CoordZ - (Taille/1.05) * sin(Pi*(60/180)), CoordA + (Taille/1.20) * cos(Pi*(60/180)), CoordZ - (Taille/1.20) * sin(Pi*(60/180)))

    can1.create_line(CoordA - (Taille/1.05) * cos(Pi*(30/180)), CoordZ + (Taille/1.05) * sin(Pi*(30/180)), CoordA - (Taille/1.20) * cos(Pi*(30/180)), CoordZ + (Taille/1.20) * sin(Pi*(30/180)))
    can1.create_line(CoordA - (Taille/1.05) * cos(Pi*(60/180)), CoordZ + (Taille/1.05) * sin(Pi*(60/180)), CoordA - (Taille/1.20) * cos(Pi*(60/180)), CoordZ + (Taille/1.20) * sin(Pi*(60/180)))

#PRINCIPLE FUNCTION (here the problem starts)

def HORLOGE1(Gamma, Pi, Epsylon):# draw a clock with the center position x/x = gamma/pi and the radius = epsylon

    fondhorloge(Gamma, Pi, Epsylon, can1)# extracting time value
    patate = gmtime()
    heure = patate[3] + 1  # "+1" is changing time from english time to french time :P
    minute = patate[4]
    seconde = patate[5]

    print(heure, minute, seconde) # a simple test to watch what the programm is doing (run it, and you'll see, that this test is done tausend time per second, that why I think the problem is here.)
    drawPetAig(Gamma, Pi, Epsylon, minute, can1)
    drawGrdAig(Gamma, Pi, Epsylon, minute, can1)
    drawSecAig(Gamma, Pi, Epsylon, seconde, can1)
    fen1.after(1000, HORLOGE1(250, 250, 200))

#execution of the main function

fen1 = Tk()
can1 = Canvas(fen1, bg="white", height=500, width=500)
can1.pack()

HORLOGE1(250, 250, 200)

fen1.mainloop()
fen1.destroy()


推荐答案

问题是在原理函数中, HORLOGE1()立即尝试调用自身,同时尝试在指定的1秒延迟后再次调用它。发生在最后一行:

The problem is that in the principle function, HORLOGE1() calls itself immediately while trying to arrange for it to be called again after the specified 1 second delay. This occurs in the last line:

fen1.after(1000, HORLOGE1(250, 250, 200))

一个简单的防止这种情况的方法是改用这样的东西:

A simple way prevent this, would be to use something like this instead:

fen1.after(1000, lambda: HORLOGE1(250, 250, 200))

此操作是使用 lambda 表达式。创建的函数不接受/不需要任何参数,它所做的只是在调用时调用 HORLOGE1(250,250,200)该函数是作为第二个参数传递给 fen1.after()的函数。

What this does is create an anonymous function using a lambda expression . The function created accepts/requires no arguments, and all it does is call HORLOGE1(250, 250, 200) when it's called. That function is what is then passed to fen1.after() as the second argument.

值得注意的是,这样做实际上 not 不会调用 HORLOGE1()过程。 .after()的第二个参数几乎总是可调用的—。例如函数或绑定方法—

The notable thing is that doing this does not actually call HORLOGE1() in the process. The second argument to .after() should almost always be a callable — such as a function or a bound method — rather than the results of calling one, as you are doing.

在进行更改之后,您应该看到这样的情况,并且要动动时钟:

After making the change, you should see something like this with moving clock hands on it:

这篇关于tkinter:模拟时钟刷新-如何在“之后”进行更新。功能工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆