2015-07-20 65 views
0

同事,無法更新TKinter圖

我正在設計一個帶兩個按鈕的圖形用戶界面,一個是顯示圖形,每小時的溫度。 我面臨的問題是我無法生成一個函數(update_graph),它使用self.after更新值。

這部分是創建第1頁和我工作的罰款,直到我打電話update_graph

class PageOne(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     label = tk.Label(self, text="Page One!!!", font=LARGE_FONT) 
     label.pack(pady=10,padx=10) 

     button1 = tk.Button(self, text="Back to Home", 
          command=lambda: controller.show_frame(StartPage)) 
     button1.pack() 

     button2 = tk.Button(self, text="Page Two", 
          command=lambda: controller.show_frame(PageTwo)) 
     button2.pack() 

     canvas = Canvas(self, width=400, height=400, bg = 'white') 
     canvas.pack() 

    # create x and y axes 
     canvas.create_line(100,250,400,250, width=2) 
     canvas.create_line(100,250,100,50, width=2) 

# creates divisions for each axle  
     for i in range(11): 
      x = 100 + (i * 30) 
      canvas.create_line(x,250,x,245, width=2) 
      canvas.create_text(x,254, text='%d'% (10*i), anchor=N) 

     for i in range(6): 
      y = 250 - (i * 40) 
      canvas.create_line(100,y,105,y, width=2) 
      canvas.create_text(96,y, text='%5.1f'% (50.*i), anchor=E) 

     self.update_graph() 

    def update_graph(self): 
# here is canvas create line that causes a trouble      
     canvas.create_line(100,250,140,200, width=2) 
     self.after(100,self.update_graph) 


Whith this code I get an error "canvas is not defined". 

If I add self to canvas in update_graph, I get 

self.canvas.create_line(100,250,140,200, width=2) 
AttributeError: 'PageOne' object has no attribute 'canvas' 

缺少什麼我在這裏?

回答

1

canvas僅在構造函數(__init__)方法的範圍內定義。如果您希望能夠在課程的其他地方訪問它,則需要將其作爲實例變量。相反的,

canvas = Canvas(self, width=400, height=400, bg = 'white') 

撐得

self.canvas = Canvas(self, width=400, height=400, bg = 'white') 

現在,其他地方在您引用canvas的代碼,將其更改爲self.canvas。這應該解決這個問題。

在一個不相關的說明中,我在update_graph中看到的一個問題是,它會遞歸地或反覆調用自身。也許你可以改變它是這樣的:

def update_graph(self): 
     # This line is quite long. Maybe you could shorten it? 
     self.after(100, lambda: canvas.create_line(100,250, 
                140,200, width=2)) 

希望這有助於!

編輯:我重新定義update_graph只有在你想要繪製一條固定線時纔有意義。如果您打算添加其他功能(如定期更新),則正如Bryan指出的那樣,原始代碼是正確的。

+0

是的,這是有區別的。謝謝 – Martin

+0

@settwi:我認爲「無關筆記」的建議是錯誤的。使用lambda的解決方案不具有相同的行爲,因爲它只會繪製一行。通過'after'調用'update_graph'對於定期運行函數來說是正確的解決方案。 –

+0

@BryanOakley,'update_graph'繪製一行固定參數。是不是一次足夠的繪製?如果它有不止一個工作要做,我不會收到評論。也許OP意在添加其他功能,在這種情況下我錯了。據此編輯。 – settwi