2014-01-15 4 views
0

Это может быть просто ограничение Tkinter, являющегося основной нитью op в первую очередь. Есть ли способ для canvas.delete(ALL) в Tkinter, когда он также использует потоки. У меня есть программа, длинная дорога, потому что она ничего не сделает, кроме как писать то, что уже на экране, когда я пытаюсь сделать delete(ALL). Если я попытаюсь исключить концепцию написания текста над текстом с цветом фона перед заменой строки новым значением (например, ниже) и заменить его на delete(ALL), тогда он ничего не делает, кроме как писать прямо назад по линии и во времени делает значение нечитаемым. Конечно, я замечаю немного оттенка исходного текста, который все еще отображается на экране, так как код написан ниже.Python tkinter threading trouble .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 полностью небезопасен. Хотя иногда это может сработать, вам будет трудно называть его надежным. Возможно, вы можете использовать Queue (поточно-безопасную реализацию, включенную в стандартные библиотеки python) и Queue команды в виде строк, затем присоединить все свои потоки и использовать Queue для выполнения команд по порядку, но в этот момент вы не используете обязательно нужны потоки. –

ответ

1

Повторяя мой комментарий. Tkinter по умолчанию небезопасен. Это можно сделать безопасно, используя объект Queue. Очереди представляют собой тип данных python, которые позволяют безопасно передавать данные потоков с использованием заблокированного стиля данных. По сути, вам нужно перевести команды из ваших потоков обратно в основной. Очередь будет иметь дело с порядком, чтобы команды не становились слишком сломанными или не в порядке. Хороший пример и где я проверил свою информацию здесь: Source