Python can';同一个函数不能用两次

Python can';同一个函数不能用两次,python,function,tkinter,time,Python,Function,Tkinter,Time,我正在尝试运行一个代码,该代码使用基于时间触发的相同函数来显示照片,而不是主照片。 第一次调用函数并返回到主照片时,它工作正常。但是当它第二次调用函数时,照片发生了变化,我看不到倒计时,程序冻结,并在终端字段中显示错误 from tkinter import * import time root=Tk() ################uper frame for Day---Date----Time##### frameup=Frame(root,highlightthickness=4,

我正在尝试运行一个代码,该代码使用基于时间触发的相同函数来显示照片,而不是主照片。 第一次调用函数并返回到主照片时,它工作正常。但是当它第二次调用函数时,照片发生了变化,我看不到倒计时,程序冻结,并在终端字段中显示错误

from tkinter import *
import time

root=Tk()
################uper frame for Day---Date----Time#####
frameup=Frame(root,highlightthickness=4,relief='solid',width=1000, height=60)
frameup.grid(row=0,column=0,columnspan=2,sticky='nsew',padx=250,pady=5)
frameup.config(highlightbackground='red3')

################lower frame############
framelow=Frame(root,highlightthickness=4,relief='solid',width=800, height=240)
framelow.grid(row=1,column=0,padx=210)
framelow.config(highlightbackground='red3')

################frame Left for the photo#############
frameL=Frame(framelow,width=380,height=20,relief='ridge',highlightthickness=1)
frameL.grid(row=0,column=0,padx=5)
frameL.config()

###############frame Right for Time Duration Countdown########
frameR=Frame(framelow)
frameR.grid(row=0,column=1,padx=5)
frameR.config(highlightbackground='green')
durationtext=Label(frameR,text='Time Remaining:',font='infra 40 bold')
durationtext.grid(row=0,column=0)

labelTD=Label(frameup)
labelTD.grid(row=0,column=0)

def countdown(n):
    mn, secs =divmod(n, 60)
    hr, mn =divmod(mn, 60)

    labelCD.config(text=f"{hr:02}:{mn:02}:{secs:02}")
    labelCD.config(font='infra 50 bold',foreground='black',background='white')

    if n >= 0:
        labelCD.after(1000, countdown, n-1)

    else:
        EYE1.forget()
        labelCD.forget()
        labelCD.destroy()
        StudioC = Label(frameL, image=photoGenral)
        StudioC.grid(row=0, column=0)


def clock():

    t=time.strftime('%A''\t''%D''\t''%H:%M:%S',time.localtime()).upper()

    if t!='':
        labelTD.config(text=t,font='infra 50 bold',foreground='red3',background='white')
        Hr = time.strftime('%H')
        Mn = time.strftime('%M')
        Sc = time.strftime('%S')

        if int(Hr)==7 and int(Mn)==54 and int(Sc)==0: ####just to trigger the timer###
            StudioC.forget()
            EYE1 = Label(frameL, image=photo1)
            EYE1.grid(row=0, column=0)
#######this condition works fine
            countdown(100)

        if int(Hr)==7 and int(Mn)==57 and int(Sc)==0:
            EYE1 = Label(frameL, image=photo1)
            EYE1.grid(row=0, column=0)
###this condition i can see the photo but I can't see countdown function and window froze
            countdown(100)

        if int(Hr)==7 and int(Mn)==59 and int(Sc)==0:
            StudioC.destroy()
            EYE1 = Label(frameL, image=photo1)
            EYE1.grid(row=0, column=0)

            countdown(100)

        labelTD.after(1000,clock)

labelCD = Label(frameR)
labelCD.grid(row=1,column=0)

photo1 = PhotoImage(file="file path.png")
EYE1 = Label(frameL, image=photo1)

#
photoGenral = PhotoImage(file="file path.png")
StudioC = Label(frameL, image=photoGenral)
StudioC.grid(row=0,column=0)


clock()
root.geometry('1775x395')

root.mainloop()

问题是,您正在销毁一个小部件,然后在销毁的小部件上使用
config()
,因此出现了错误。您可以改为使用
grid\u-forget()
,然后在每次迭代中使用
grid()
,例如:

def countdown(n):
    mn,secs = divmod(n, 60)
    hr,mn = divmod(mn, 60)

    labelCD.grid(row=1,column=0) 
    labelCD.config(text=f"{hr:02}:{mn:02}:{secs:02}",font='infra 50 bold',
                    foreground='black',background='white')

    if n >= 0:
        labelCD.after(1000, countdown, n-1)

    else:
        EYE1.grid_forget() #hide the widget
        
        if labelCD.winfo_exists(): #if this widget is exists
            labelCD.grid_forget() #then hide
        
        StudioC = Label(frameL, image=photoGenral) #this overlaps the current image
        StudioC.grid(row=0, column=0)
如果要在每个
If
语句上显示备用图像,可以使用计数器之类的东西,在每次迭代中增加,然后如果是偶数,则
将标签配置为具有一个图像,如果不是,则
将其配置为具有另一个图像

另外,我不使用
divmod()
,而是使用
datetime
中的
timedelta
,如:

from datetime import timedelta
....
def countdown(n):
    count = timedelta(seconds=n)

    labelCD.grid(row=1,column=0)
    labelCD.config(text=count,font=.....)
#same code

这样,您也可以从一些计算和格式中节省自己。

问题是,您正在销毁一个小部件,然后在销毁的小部件上使用
config()
,因此会出现错误。您可以改为使用
grid\u-forget()
,然后在每次迭代中使用
grid()
,例如:

def countdown(n):
    mn,secs = divmod(n, 60)
    hr,mn = divmod(mn, 60)

    labelCD.grid(row=1,column=0) 
    labelCD.config(text=f"{hr:02}:{mn:02}:{secs:02}",font='infra 50 bold',
                    foreground='black',background='white')

    if n >= 0:
        labelCD.after(1000, countdown, n-1)

    else:
        EYE1.grid_forget() #hide the widget
        
        if labelCD.winfo_exists(): #if this widget is exists
            labelCD.grid_forget() #then hide
        
        StudioC = Label(frameL, image=photoGenral) #this overlaps the current image
        StudioC.grid(row=0, column=0)
如果要在每个
If
语句上显示备用图像,可以使用计数器之类的东西,在每次迭代中增加,然后如果是偶数,则
将标签配置为具有一个图像,如果不是,则
将其配置为具有另一个图像

另外,我不使用
divmod()
,而是使用
datetime
中的
timedelta
,如:

from datetime import timedelta
....
def countdown(n):
    count = timedelta(seconds=n)

    labelCD.grid(row=1,column=0)
    labelCD.config(text=count,font=.....)
#same code


通过这种方式,您也可以避免某些计算和格式。

终端窗口中显示了什么错误?@scotty3785它不止一行错误,但两行特定的是倒计时功能中的第三行和窗口冻结时的第二个If条件。请复制过去并添加两张照片,以准确了解我在说什么。请用完整的错误代码更新问题。Tkinter回调回溯(最近一次调用)中的异常:文件“/\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,在时钟倒计时(100)文件“/”中,第38行,在倒计时labelCD.config(text=f“{hr:02}:{mn:02}:{secs:02}”文件“//”init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu".!框架2。!框架2。!标签2“我不得不删除一些显示路径的文字,这些文字的字母数必须正确。谢谢终端窗口中显示了什么错误?@scotty3785它不止一行错误,但两行特定的错误是倒计时功能中的第三行和窗口冻结时的第二个If条件。请复制过去并添加两张照片,以准确了解我在说什么。请用完整的错误代码更新问题。Tkinter回调回溯(最近一次调用)中的异常:文件“/\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,在时钟倒计时(100)文件“/”中,第38行,在倒计时labelCD.config(text=f“{hr:02}:{mn:02}:{secs:02}”文件“//”init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu".!框架2。!框架2。!标签2“我不得不删除一些显示路径的文字,这些文字的字母数必须正确。谢谢我不认为
timedelta
给出的小时/分钟/秒只是天/分钟/秒。我错了,如果你得到字符串的话。只是不能作为像
count.hours
@scotty3785这样的属性使用,对吗?这可能是因为
timedelta
给出了一个
datetime.timedelta
对象,它没有
hours
属性,不像
datetime.datetime
对象。@scotty3785我想酷云有正确的答案。我照他说的做了,它起作用了。我不认为
timedelta
给出的小时/分钟/秒只是天/分钟/秒。我错了,如果你得到了字符串。只是不能作为像
count.hours
@scotty3785这样的属性使用,对吗?这可能是因为
timedelta
给出了一个
datetime.timedelta
对象,它没有
hours
属性,不像
datetime.datetime
对象。@scotty3785我想酷云有正确的答案。我照他说的做了,这很有效