Python / Tkinter:使用大画布销毁窗口会导致程序停止响应

时间:2012-06-19 14:42:09

标签: python tkinter

我正在使用Tkinter维护一个用Python编写的图形化解析应用程序。它可选地在可滚动的电子表格中显示其结果,我使用Canvas小部件创建。但是,它似乎有一些可扩展性问题。当主画布太大时,试图破坏显示结果的窗口会导致程序停止响应并需要被杀死。当显示的数据较少时,我可以正常销毁它。这是Tkinter /大型Canvi的已知问题吗?我能做些什么来防止这些冻结吗?

#Function being called to destroy window
def justexit():
    savepopup.destroy() #Destroy the popup asking to save (that called this function)
    deleteall() #Destroy canvi and their contents
    popup.destroy() #Destroy the window containing all the canvi

def deleteall():
    for i, itemset in enumerate(items): #Items stores lists containing every item added to the canvi
        for item in itemset:
            canvi[i].delete(item)
        canvi[i].destroy()

我估计有点偏。确实有多达数万种物品在玩耍,但我不认为这种减速会如此明显。

1 个答案:

答案 0 :(得分:1)

是的,canvas小部件存在可伸缩性问题。通常,只有在画布上有数万个项目时才会启动。你有几个项目?

我依稀回忆起如果你在删除画布之前删除这些项目可能会更快。不过,我不知道这是事实。

尝试运行以下代码。它创建了5000个随机矩形。当您单击删除按钮时,它将删除画布小部件,并且在我的机器上这是即时的。

import Tkinter as tk
import random

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.wm_geometry("400x400")
        self.del_button = tk.Button(text="delete", command=self.delete)
        self.del_button.pack()
        self.create_button = tk.Button(text="create", command=self.create)
        self.create_button.pack()
        self.canvas = None
        self.create()

    def create(self):
        if self.canvas is not None:
            self.canvas.destroy()
        self.canvas = tk.Canvas(self)
        self.canvas.pack(side="top", fill="both", expand=True)
        colors = ["red","orange","green","blue", "violet","bisque","white"]
        for i in range(5000):
            x0 = random.random()*400
            y0 = random.random()*400
            width = random.randint(10,100)
            height = random.randint(10,100)
            x1 = x0 + width
            y1 = y0 + height
            color = colors.pop(0)
            colors.append(color)
            self.canvas.create_rectangle(x0,y0,x1,y1, outline="black", fill=color)
        
    def delete(self):
        self.canvas.destroy()
        self.canvas = None

app = SampleApp()
app.mainloop()