【问题标题】:can't use the same function twice不能两次使用相同的功能
【发布时间】:2021-03-18 19:32:39
【问题描述】:

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

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

【问题讨论】:

  • 终端窗口显示什么错误?
  • @scotty3785 它的错误不止一行,但这两行具体是倒计时功能中的第三行和窗口冻结时的第二个 If 条件。请复制过去并添加两张照片以确切了解我在说什么。
  • 请用完整的错误代码更新问题。
  • Tkinter 回调 Traceback 中的异常(最近一次调用最后一次):文件“//__init__.py”,第 1885 行,在 call__return self.func(*args) 文件“//__init.py",第 806 行,在 callit func(*args) 文件“/”,第 78 行,时钟倒计时 (100) 文件“/”,第 38 行,倒计时 labelCD.config(text=f"{ hr:02}:{mn:02}:{secs:02}") File "//__init__.py", line 1639, in configure return self._configure('configure',cnf, kw) File "//__init__ .py”,第 1629 行,在 _configure self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))_tkinter.TclError:无效命令名称“.!frame2.!frame2.!label2 "
  • 我不得不删除一些显示路径的文本以正确计数。谢谢!

标签: python function tkinter time


【解决方案1】:

问题是,您正在销毁一个小部件,然后在已销毁的小部件上使用config(),因此出现错误。你可以做的是在每次迭代中使用grid_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 语句上显示替代图像,您可以使用像计数器这样的东西,它会在每次迭代中增加,然后如果它是 configure,则标签有一个图像,如果不是,那么configure 拥有另一张图片。

我也不会使用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

这样,您也可以避免一些计算和格式。

【讨论】:

  • 我不认为timedelta 只给出了小时/分钟/秒数天/分钟/秒
  • 我的错,如果你得到了字符串,它就会发生。只是不能作为 count.hours 之类的属性使用
  • @scotty3785 有点帮助吧?这可能是因为timedelta 提供了一个没有hours 属性的datetime.timedelta 对象,这与datetime.datetime 对象不同。
  • @scotty3785 我猜酷云有正确的答案。我照他说的做了,而且效果很好
猜你喜欢
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多