windows thinks tkinter is not responding

后端 未结 1 936
眼角桃花
眼角桃花 2021-01-24 19:11

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 th

相关标签:
1条回答
  • 2021-01-24 19:35

    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.

    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()
    
    0 讨论(0)
提交回复
热议问题