keeping console control in tkinter using threading
I believe using global variables in this code is just an easy way to access the data from Python REPL (since the code is supposed to be for teaching purposes). But keeping the Tk object in a global variable and access it from different threads is the root of this issue.
I think setting master
(global variable) to a new Tk object on each new launch could help. So we could make sure previous Tk object is garbage collected when launch()
is finished and It's thread is joined.
Here are the changed functions (comments show which parts are changed).
# import garbage collection moduleimport gcdef threadmain(): global master master = tk.Tk() master.title("stuff") drawzone = tk.Canvas(master, width=300, height = 300, bg='white') drawzone.pack() def queueloop(): try: callable_, args, kwargs = request_queue.get_nowait() except queue.Empty: pass else: callable_(*args, **kwargs) master.after(500, queueloop) queueloop() master.mainloop() # added these 2 lines to remove previous Tk object when thread is finished master = None gc.collect()def launch(): global mythread,request_queue # added these 3 lines to end previous open thread if any if mythread and mythread.isAlive(): submit_to_tkinter(master.destroy) mythread.join() request_queue = queue.Queue() mythread = Thread(target=threadmain, args=()) # no need for daemon threads # mythread.daemon=True mythread.start()
Now on each call to launch()
it will close previous Tk window and wait for the thread to join, before opening a new Tk in a new thread.