2014-01-15 51 views
0

這可能僅僅是Tkinter主要線程的限制。在使用線程時,在Tkinter中有沒有辦法使用canvas.delete(ALL)?我的程序正在運行,漫長的路要走,因爲當我嘗試delete(ALL)時,它不會執行任何操作,而只會寫入屏幕上已有的內容。如果我試圖消除self.line1, self.line2在用新值替換線條(如下所示)之前用背景顏色回寫文本的概念,並將其替換爲delete(ALL),那麼它不會執行任何操作,而是直接寫回線和時間使價值無法讀取。當然,我注意到原始文本的色調仍然以下面的代碼的方式出現在屏幕上。Python tkinter線程麻煩.delete(ALL)

此外,是否有一個簡短的方式跳出self.after循環,一旦子線程都完成運行。我知道我可以輕鬆地創建一個大規模的if系列語句來測試所有內容,然後在所有內容完成時結束。當你有11個線程在運行時,你會通過一個簡短的方式來測試嗎?

import os 
import sys 
import urllib 
import tkinter as tk 
import threading 
import time 

os.chdir ('/media') 

class GUI(tk.Frame): 
     def __init__(self,master): 
       tk.Frame.__init__(self,master) 
       self.DrawArea = tk.Canvas(self, width = 200, height = 250, background = 'black', 
           borderwidth = 0, highlightthickness = 0) 
       self.DrawArea.grid(row=0, column=0, sticky="nsew") 
       self.grid_rowconfigure(0, weight=1) 
       self.grid_columnconfigure(0, weight=1) 
       self.NxtNum0=0 
       self.NxtNum1=0 
       self.HiStr0=0 
       self.HiStr1=0 
       #find highest download video 
       Hival = open("Highest.txt", "r") 
       self.HiStr = Hival.read() 
       Hival.close() 
       self.HiStr0 = str(int(self.HiStr)+1) 
       self.HiStra = int(int(self.HiStr)/10000) 

       #call download #0 
       dl0 = threading.Thread(target = self.dl_0, name = 'dl0') 
       dl0.start() 

       #setup/call download #1 
       self.HiStr1 = str(str(self.HiStra+1)+"0000") 
       dl1 = threading.Thread(target = self.dl_1, name = 'dl1') 
       dl1.start() 

       self.line1=0 
       self.line2=0 
       self.real_time() 

     def real_time(self): 
       self.DrawArea.create_text(50,12,text = self.line1, fill = 'black') 
       self.DrawArea.create_text(50,27,text = self.line2, fill = 'black') 
       self.line1 = str(self.NxtNum0) 
       self.line2 = str(self.NxtNum1) 
       self.DrawArea.create_text(50,12,text = self.line1, fill = 'white') 
       self.DrawArea.create_text(50,27,text = self.line2, fill = 'white') 
       self.after(1000, self.real_time) 

     def dl_0(self): 
       self.NxtNum0 = int(self.HiStr0) 
       while self.NxtNum0 < int(self.HiStr0)+100: 
         self.NxtNum0 +=1 
         time.sleep(.1) 

     def dl_1(self): 
       self.NxtNum1 = int(self.HiStr1) 
       while self.NxtNum1 < int(self.HiStr1)+100: 
         self.NxtNum1 +=1 
         time.sleep(.1) 


root = tk.Tk() 
GUI(root).pack(fill = "both", expand = True) 
+0

如果我沒有記錯,Tkinter是完全線程不安全的。雖然它有時可能有效,但你很難把它稱爲可靠的。你可以使用一個隊列(一個線程安全的實現包含在標準的Python庫中)並將這些命令作爲字符串排隊,然後加入你所有的線程並使用Queue按順序執行命令,但是在那一點上,你不一定需要線程。 –

回答

1

重複我的評論。 Tkinter默認是不安全的。它可以使用Queue對象安全地完成。隊列是一種python數據類型,它允許使用鎖定的數據樣式傳遞安全的線程數據。實質上,你需要將你的線程中的命令傳回給main。隊列將處理排序,以便命令不會被破壞或失序。一個很好的例子,我驗證我的信息在這裏:Source