Windows 认为 tkinter 没有响应 [英] windows thinks tkinter is not responding
问题描述
我在 python 中有一个小应用程序,除了这个小问题外,它工作正常:它应该连续运行一个循环,直到用户通过按钮告诉它停止,但是当我点击开始按钮时,Windows 告诉我它不是回应.现在,如果我编写一个简单的打印语句,一切正常:
I have a little app in python, which works fine except for this minor problem: it supposed to run a loop continuously, until the user tells it stop via button, but when I hit the start button, windows tells me it's not responding. Now if I write a simple print statement everything works fine:
def update(self):
self.bStart.config(state = 'disabled')
self.bStop.config(state = 'active')
self.running = True
self.toRun = True
while self.toRun:
[...do some stuff...]
time.sleep(self.toWait)
print("i'm alive")
但是,如果没有 print 语句,它只会冻结并进入无响应"状态,我在想是否有办法防止这种情况发生.
however, without the print statement, it just freezes and goes to 'not responding', and I am wandering whether there's a way to prevent that.
推荐答案
作为一般规则,您不应在 GUI 中调用 sleep
,也不应使用循环来更新展示.如果您定期更新显示,正确使用 after
会使循环变得不必要.
As a general rule, you shouldn't be calling sleep
in a GUI, and you shouldn't have loops that update the display. If you're periodically updating the display, proper use of after
makes a loop unnecessary.
一般的想法是编写一个执行单个更新的函数(即:否则您将拥有作为循环体的内容).然后,让该函数通过 after
调用自身.
The general idea is to write a function that does a single update (ie: what you would otherwise have as the body of a loop). Then, have that function call itself via after
.
下面是一个示例,您可以在不使用循环的情况下看到条形图随时间增长:
Here's an example where you can see a bar chart grow over time, without using a loop:
import Tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.canvas = tk.Canvas(self)
self.start_button = tk.Button(self, text="start", command=self.on_start)
self.stop_button = tk.Button(self, text="stop", command=self.on_stop)
self.start_button.pack()
self.stop_button.pack()
self.canvas.pack(fill="both", expand=True)
# call on_stop to initialize the state of the buttons
self.on_stop()
def on_start(self):
"""Start the animation"""
self.canvas.delete("all")
self.rect_id = self.canvas.create_rectangle(0,0,1,20, fill="blue")
self.running = True
self.start_button.configure(state="disabled")
self.stop_button.configure(state="normal")
self.draw_one_frame()
def on_stop(self):
"""Stop the animation"""
self.start_button.configure(state="normal")
self.stop_button.configure(state="disabled")
self.running = False
def draw_one_frame(self):
"""Draw a single frame of animation"""
(x0, y0, x1, y1) = self.canvas.coords(self.rect_id)
if x1 < self.canvas.winfo_width():
x1 += 1
else:
x1 = 1
self.canvas.coords(self.rect_id, (x0, y0, x1, y1))
if self.running:
self.after(10, self.draw_one_frame)
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
这篇关于Windows 认为 tkinter 没有响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!