Python 倒计时计时器未在tkinter中更新

Python 倒计时计时器未在tkinter中更新,python,tkinter,Python,Tkinter,我正在尝试使用python和tkinter构建一个支付应用程序。有一个“主”程序,它从用户那里获取卡号、cvv等详细信息,并将其发送到另一个程序,即支付网关 因此,它不是一个真正的支付网关。它只是用数据库交叉检查卡号、cvv等 我的代码中没有包含主程序,因为我可以向您保证,我已经检查了值是否已成功地从主程序传输,并且确实如此 下面的程序有点长,很抱歉,但我会尽量集中精力解决这个问题 这是“支付网关”: 主程序导入该程序,运行visa卡支付功能,并提供所需的值 开始时,程序运行一个查询,查看行数是

我正在尝试使用python和tkinter构建一个支付应用程序。有一个“主”程序,它从用户那里获取卡号、cvv等详细信息,并将其发送到另一个程序,即支付网关

因此,它不是一个真正的支付网关。它只是用数据库交叉检查卡号、cvv等

我的代码中没有包含主程序,因为我可以向您保证,我已经检查了值是否已成功地从主程序传输,并且确实如此

下面的程序有点长,很抱歉,但我会尽量集中精力解决这个问题

这是“支付网关”:

主程序导入该程序,运行visa卡支付功能,并提供所需的值

开始时,程序运行一个查询,查看行数是否为1,获取所需的电子邮件ID,并输入t=300的倒计时(t)

然后,它生成一个随机的otp,为此发送一封电子邮件,并创建一个新窗口,要求用户输入otp。这就是麻烦的开始

我有一个倒计时标签2,最初有5:00有文字。然后我有一个while(t)函数来倒计时5分钟

每过一秒,它都必须忘记上一个倒计时标签2的位置,创建一个新标签,其文本比该标签短一秒,然后重新放置

它将运行程序5分钟,在这5分钟内,如果输入并提交了正确的otp,那么它将显示它成功,否则它将重复两次尝试,并且在倒计时内也会重复

电子邮件已成功接收,但倒计时标签2未更新,它保持在5:00

我以为问题出在我放置root.mainloop()的地方,但我在上面代码中放置它的地方只起作用,否则otp屏幕不会出现

这是otp屏幕:

如果单击submit,将显示一个新窗口,其中包含给定的root.title(),但其中没有显示任何内容(我有一个成功标签,但没有显示)

如果我关闭屏幕,则显示以下内容:

我真的很抱歉为了一个小任务而浪费你的时间阅读这么多,但如果你能帮上忙,我将不胜感激

谢谢


注:def visa卡支付功能下的所有内容都必须缩进。

这里有一些基本的Tkinter规则被打破

  • 永远不要有多个tkinter Tk根方法(它们不会很好地共存)
  • 永远不要使用无限while循环(它们会阻止gui更新)
  • 要解决1,请对任何子窗口使用Toplevel而不是Tk

    解2有点复杂

    包含倒计时的while循环将不会执行,因为root.mainloop()将 继续运行,直到GUI关闭

    你应该考虑把倒计时定时器放在一个单独的函数中,它由TKTETER每秒调用一次。 当按下按钮时,您可以在一秒钟后调用类似的函数

    root.after(1000, myCountdownFunction)
    
    那么你的函数看起来像

    def myCountDownFunction():
        mins, secs = divmod(t, 60)
        timeformat='{:02d}:{:02d}'.format(mins, secs)
        countdown_label2.grid_forget()
        countdown_label2=Label(root,text=timeformat)
        countdown_label2.grid(row=1,column=1)
        t=-1
        root.after(1000, MyCountdownFunction) # Calls this function again in 1 second
    

    这个问题非常广泛,我怀疑任何答案都不能完全解决您的问题,而不需要重新编写代码。

    为什么没有人回答?我只能建议您就您的问题举一个更简单的例子。现在你的代码包括f.ex。发送电子邮件,这与您的问题无关,对吗?是的,我会这样做。感谢您抽出时间回答这个问题。它现在工作得很好
    def myCountDownFunction():
        mins, secs = divmod(t, 60)
        timeformat='{:02d}:{:02d}'.format(mins, secs)
        countdown_label2.grid_forget()
        countdown_label2=Label(root,text=timeformat)
        countdown_label2.grid(row=1,column=1)
        t=-1
        root.after(1000, MyCountdownFunction) # Calls this function again in 1 second