2012-06-19 100 views
0

我正在用Tkinter維護用Python編寫的圖形分析應用程序。它可選擇將其結果顯示在一個可滾動的電子表格中,我使用Canvas小部件創建該電子表格。但是,它似乎有一些可擴展性問題。當主畫布太大時,試圖銷燬顯示結果的窗口會導致程序停止響應並需要被終止。當顯示的數據較少時,我可以正常銷燬它。這是Tkinter/large Canvi的一個已知問題嗎?我可以做任何事情來防止這些凍結?Python/Tkinter:用大畫布銷燬窗口會導致程序停止響應

#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

是的,畫布部件有可擴展性問題。通常情況下,只有在畫布上有數以萬計的項目時纔會啓動。你有多少物品?

我隱約地想起,如果在刪除畫布之前刪除項目,它可能會更快。不過,我不知道這是事實。

嘗試運行以下代碼。它創建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() 
+0

是的,我似乎刪除項目之前刪除canvi ...我沒想到我有超過1000個項目上。 – dpitch40

+0

@ dpitch40:你的意思是「似乎正在刪除」?要麼是在摧毀畫布之前明確刪除它們,要麼是不是。 1000件物品在最壞情況下不應造成超過一秒或兩秒的延遲。是否有可能不斷創建對象並隱藏舊對象而不實際刪除它們?這通常是在有人遇到這個問題時發生的。 –

+0

我保存在每個畫布上創建的所有項目(文本和線條),然後在刪除窗口時遍歷它們全部存儲的位置,並在銷燬畫布本身之前調用畫布的每個刪除方法。但是,我已經確定它在銷燬窗戶本身時掛起,而不是罐頭或任何東西。我可以很好地運行你的代碼。我會添加一些關於銷燬canvi的代碼。 – dpitch40