multithreading - Threads and tkinter python 3 -
multithreading - Threads and tkinter python 3 -
i've heard threads in python not easy handle , become more tangled tkinter.
i have next problem. have 2 classes, 1 gui , infinite process. first, start gui class , infinite process' class. want when close gui, finishes infinite process , programme ends.
a simplified version of code following:
import time, threading tkinter import * tkinter import messagebox finish = false class tkintergui(threading.thread): def __init__(self): threading.thread.__init__(self) def run(self): global finish #main window self.mainwindow = tk() self.mainwindow.geometry("200x200") self.mainwindow.title("my gui title") #label lbcommand = label(self.mainwindow, text="hello world", font=("courier new", 16)).place(x=20, y=20) #start self.mainwindow.mainloop() #when gui closed set finish "true" finish = true class infiniteprocess(threading.thread): def __init__(self): threading.thread.__init__(self) def run(self): global finish while not finish: print("infinite loop") time.sleep(3) gui = tkintergui() gui.start() process = infiniteprocess() process.start()
when click in close button (in upper right corner) next error appears in console:
tcl_asyncdelete: async handler deleted wrong thread
i dont know why happens or means, ¡please help!
all tcl commands need originate same thread. due tkinter
's dependence on tcl, it's necessary create tkinter
gui statements originate same thread. problem occurs because mainwindow
instantiated in tkintergui
thread, -- because mainwindow
attribute of tkintergui
-- not destroyed until tkintergui
destroyed in main thread.
the problem can avoided not making mainwindow
attribute of tkintergui
-- i.e. changing self.mainwindow
mainwindow
. allows mainwindow
destroyed when run
method ends in tkintergui
thread. however, can avoid threads exclusively using mainwindow.after
calls instead:
import time, threading tkinter import * tkinter import messagebox def infinite_process(): print("infinite loop") mainwindow.after(3000, infinite_process) mainwindow = tk() mainwindow.geometry("200x200") mainwindow.title("my gui title") lbcommand = label(mainwindow, text="hello world", font=("courier new", 16)).place(x=20, y=20) mainwindow.after(3000, infinite_process) mainwindow.mainloop()
if want define gui within class, can still so:
import time, threading tkinter import * tkinter import messagebox class app(object): def __init__(self, master): master.geometry("200x200") master.title("my gui title") lbcommand = label(master, text="hello world", font=("courier new", 16)).place(x=20, y=20) def tkintergui(): global finish mainwindow = tk() app = app(mainwindow) mainwindow.mainloop() #when gui closed set finish "true" finish = true def infiniteprocess(): while not finish: print("infinite loop") time.sleep(3) finish = false gui = threading.thread(target=tkintergui) gui.start() process = threading.thread(target=infiniteprocess) process.start() gui.join() process.join()
or simpler, utilize main thread run gui mainloop:
import time, threading tkinter import * tkinter import messagebox class app(object): def __init__(self, master): master.geometry("200x200") master.title("my gui title") lbcommand = label(master, text="hello world", font=("courier new", 16)).place(x=20, y=20) def infiniteprocess(): while not finish: print("infinite loop") time.sleep(3) finish = false process = threading.thread(target=infiniteprocess) process.start() mainwindow = tk() app = app(mainwindow) mainwindow.mainloop() #when gui closed set finish "true" finish = true process.join()
python multithreading tkinter tcl
Comments
Post a Comment