为什么一段时间后我的Tkinter顶层冻结?

时间:2018-08-17 16:58:28

标签: python python-3.x tkinter

我在主窗口和顶层都运行着秒表。一旦启动程序,手表便会启动,并通过关闭程序使其停止。通过使用按钮启动顶层。顶层应该显示秒表的副本。但是,当我将顶层打开一个小时以上时,它就会冻结。主窗口运行良好。当我手动关闭并重新打开它时,顶层可以再工作一个小时左右。有谁知道可能是什么问题?我正在Windows操作系统上运行代码。

以下是相关代码:

import datetime
import time
import tkinter as tk

time_elapse_flag = False
start_time = datetime.datetime.now()
diff = 0

def time_elapse():
    global time_elapse_flag
    global diff

    if(not time_elapse_flag):      
            time_elapse_flag = True
            time_elapse_count = tk.Label(window, text='', relief='sunken', bg='white', font='Helvetica 16 bold')
            time_elapse_count.place(x=10, y=150, width=200, height=50)
            start_time = datetime.datetime.now().replace(microsecond=0)

            time_elapse_label = tk.Label(window, text='Recording data since:', font='Helvetica 12 bold')
            time_elapse_label.place(x=10, y=120, width=200, height=30)

            def update_time():
                global start_time
                global diff
                current_time = datetime.datetime.now().replace(microsecond=0)
                diff = current_time - start_time
                time_elapse_count.config(text=diff)
                time_elapse_label.after(1000,update_time)

            update_time()

    else:
        time_elapse_flag = False
        time_elapse_count = tk.Label(window, text='')
        time_elapse_count.place(x=10, y=150, width=200, height=50)

        time_elapse_label = tk.Label(window, text='')
        time_elapse_label.place(x=10, y=120, width=200, height=30)

def Param_Window():   
    global time_elapse_flag
    global diff

    pw = tk.Toplevel()
    pw.geometry('1200x550') 

    def update_values():
        global diff

        if(time_elapse_flag):
                time_elapse_label = tk.Label(pw, text='Recording data since:', font='Helvetica 20 bold')
                time_elapse_count = tk.Label(pw, text=diff, relief='sunken', bg='white', font='Helvetica 16 bold')
                time_elapse_label.place(x=640, y=350, width=300, height=50)
                time_elapse_count.place(x=640, y=400, width=200, height=50)
        else:
                time_elapse_label = tk.Label(pw, text='')
                time_elapse_count = tk.Label(pw, text='')
                time_elapse_label.place(x=640, y=350, width=300, height=50)
                time_elapse_count.place(x=640, y=400, width=200, height=50)

        pw.after(800,update_values)

    update_values()

if __name__ == "__main__":
    window = tk.Tk()
    window.geometry('550x250')

    disp_param_button = tk.Button(window, text='Display Parameters', command=Param_Window, bg='sky blue', font='Helvetica 12 bold', width=20, state='normal', relief='raised')
    disp_param_button.place(x=300, y=150)
    print('Automatically starting in')

    for cd in range(5):
        print(5-cd)
        time.sleep(1)

    time_elapse()

    window.mainloop( )

2 个答案:

答案 0 :(得分:1)

问题在于您每Param_Window中每800毫秒创建两个新的标签小部件。当您运行一个小时时,这意味着您将创建4,500个标签小部件。在某个时候,您将达到一个严格的限制,因为您不能创建无限数量的小部件。

您需要重组代码,以便一次创建标签,然后重新配置标签,而不是每次迭代都创建新的小部件。

答案 1 :(得分:0)

要添加到Bryan的答案中,您还应该将睡眠代码移到tk实例之外并修复缩进。

这是您的代码的更正版本,它将解决我所看到的所有问题。

  1. 缩进修复

  2. 睡眠已移出tk实例(与您的主要问题无关,但同样是错误的)

  3. 更改了Param_Window函数以更新标签,而不是每隔0.8秒重新创建它们。

代码:

import tkinter as tk
import datetime
import time

time_elapse_flag = False
start_time = datetime.datetime.now().replace(microsecond=0)

def time_elapse():
    global time_elapse_flag
    global diff

    if(not time_elapse_flag):      
        time_elapse_flag = True
        time_elapse_count = tk.Label(window, text='', relief='sunken', bg='white', font='Helvetica 16 bold')
        time_elapse_count.place(x=10, y=150, width=200, height=50)
        start_time = datetime.datetime.now().replace(microsecond=0)

        time_elapse_label = tk.Label(window, text='Recording data since:', font='Helvetica 12 bold')
        time_elapse_label.place(x=10, y=120, width=200, height=30)

        def update_time():
            global start_time
            global diff
            current_time = datetime.datetime.now().replace(microsecond=0)
            diff = current_time - start_time
            time_elapse_count.config(text=diff)
            time_elapse_label.after(1000, update_time)

        update_time()

    else:
        time_elapse_flag = False
        time_elapse_count = tk.Label(window, text='')
        time_elapse_count.place(x=10, y=150, width=200, height=50)

        time_elapse_label = tk.Label(window, text='')
        time_elapse_label.place(x=10, y=120, width=200, height=30)


def Param_Window():   
    global time_elapse_flag
    global diff

    pw = tk.Toplevel()
    pw.geometry('1200x550') 
    time_elapse_label = tk.Label(pw, text='Recording data since:', font='Helvetica 20 bold')
    time_elapse_count = tk.Label(pw, text=diff, relief='sunken', bg='white', font='Helvetica 16 bold')
    time_elapse_label.place(x=640, y=350, width=300, height=50)
    time_elapse_count.place(x=640, y=400, width=200, height=50)

    def update_values():
        global diff

        if(time_elapse_flag):
            time_elapse_label.config(text='Recording data since:')
            time_elapse_count.config(text=diff)

        else:
            time_elapse_label.config(text='')
            time_elapse_count.config(text='')

        pw.after(800, update_values)

        update_values()

if __name__ == "__main__":

    print('Automatically starting in')

    for cd in range(5):
        print(5-cd)
        time.sleep(1)

    window = tk.Tk()
    window.geometry('550x250')

    disp_param_button = tk.Button(window, text='Display Parameters', command=Param_Window, bg='sky blue', font='Helvetica 12 bold', width=20, state='normal', relief='raised')
    disp_param_button.place(x=300, y=150)

    time_elapse()
    window.mainloop()