Reputation: 1323
This may simply be the limitation of Tkinter being main thread op primarily. Is there a way to canvas.delete(ALL)
in Tkinter when also using threads. I have the program running, the long way around because it won't do anything but write over what is already on the screen when I try to delete(ALL)
. If I try to eliminate self.line1, self.line2
concept of writing back over the line of text with the background color before replacing the line with the new value(like below) and replace it with delete(ALL)
then the it doesn't do anything but write right back over the line and in time makes the value unreadable. Granted I do notice a bit of a tint of the original text still showing up on the screen with the way the code is written below.
Also, is there a short way of jumping out of the self.after
loop once the child threads are all done running. I know I could easily create a massive if
series of statements to test everything and then cause it to end when all is finished. Is there a short way though when you have 11 threads running that you would be testing through?
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)
Upvotes: 0
Views: 150
Reputation: 1533
Repeating my comment. Tkinter by default is not safe. It can be done safely using a Queue object. Queues are a python data type that allow for safe thread data passing using a locked data style. Essentially, you need to pipe commands from your threads back to main. The queue will deal with ordering so that commands don't get too broken or out of order. A good example and where I verified my information is here: Source
Upvotes: 1