tkinter窗口在一段时间后冻结

时间:2019-09-23 23:12:26

标签: python python-3.x tkinter

我是Tkinter的新手。我正在对此进行试验,但是虽然Tkinter可以很好地启动,但一段时间后它会无缘无故死机。实际上,发生的怪异事情是,虽然Tkinter窗口不再更新信息,但计数器仍在我的WINDOWS桌面左上侧继续打印! (只是带有白色字体的黑色bg框显示计数器编号),最后找到编号777并结束。但是即使没有任何打印,两者之间也会长时间冻结(在我的Windows桌面上也没有)

this is the normal tkinter window this is the console output 一切都很好

crazy Windows display here

这里的简单程序正在生成1-10000之间的随机整数,并且应该1)如果找到777,则应打印计数器,然后退出2)如果找到1-100之间的任何数字,则应打印数字和计数器。

我正在尝试学习如何在同一行中打印新内容,并且如果发生某些情况,则在另一行中打印更多信息,而第一行(或更多行)会不断更新。

我不确定是否以正确的方式退出程序,或者不确定应该使用/调用Tkinter函数更新屏幕上的信息的方式。

任何帮助或提示,我们将不胜感激。

from tkinter import *
import random
import time

tk=Tk()
i = 0
counter = 0

tk.title("Testing...")
tk.geometry('300x200')

canvas_width = 200
canvas_height = 100
canvas = Canvas(tk, width=canvas_width, height=canvas_height, bg='white')
canvas.pack(expand=YES)

def screen(Found):
    #canvas.create_text(20, 20, text="Counter:" + str(counter), font="Times 20 italic")
    widget = Label(canvas, text="Counter:" + str(counter), fg='white', bg='black')
    widget.grid(column=0, row=0)
    if Found:
        widget = Label(canvas, text="Number " + str(i) +" was found at counter:" + str(counter), fg='white', bg='black')
        widget.grid(column=0, row=1)

found = False

loop = True
while loop:
    counter += 1
    i = random.randint(1, 10000)

    if i in range(1, 100):
        print("Found i = ", i, " in counter:", counter)
        Found = True
    else:
        Found = False

    if i == 777:
        loop = False
        print("JUST FOUND 777")
        print("Counter:", counter)

    screen(Found)
    tk.update_idletasks()
    tk.update()

# tk.mainloop()

2 个答案:

答案 0 :(得分:0)

之所以似乎将其冻结至少部分原因是因为您有一个永无止境的循环,永远不会中断。大多数情况下,i不会在1到100的范围内,也不会是777,但是您的循环将继续运行并且永远不会更新屏幕。

您还每秒创建数百或数千个标签小部件,它们彼此堆叠。您会很快遇到性能问题。

答案 1 :(得分:0)

就设计而言,通常最好的方法是依靠tkinter主循环来驱动应用程序。 root.after是while循环的绝佳替代品。标签不需要重新创建;他们可以使用特殊变量来自行更新显示的值,并且可以重新配置其属性。几乎不需要调用updateupdate_idletasks

以下是从tkinter主循环驱动的循环中更新单个标签的更好方法:
(它向您显示“如何继续显示新内容,而不会出现此类标签问题”

import tkinter as tk
import random

def screen(found, v, c):
    if found:
        label.configure(bg='red', fg='blue')
        print('found')
    else:
        label.configure(bg='black', fg='white')
    update_lbl_txt(v, c)

def update_lbl_txt(v=0, c=0):
    txt = f'Number at {v} was found at counter {c}'
    lbl_txt.set(txt)

def found_target(t):
    return t in range(1, 100) or t == 777

def loop(c=0):
    v = random.randint(1, 10000)
    screen(found_target(v), v, c)
    root.after(100, loop, c+1)

root = tk.Tk()

root.title("Testing...")
root.geometry('300x200')

lbl_txt = tk.StringVar(root)
update_lbl_txt()
label = tk.Label(root, textvariable=lbl_txt, fg='white', bg='black')
label.pack(expand=True, fill=tk.BOTH)

loop()

root.mainloop()