Reputation: 21
I'm trying to write a Python GUI program with tkinter.
I want to make two thread. One runing with the main_form function to keep tkinter from keep update and loop (avoid "Not Responding").
The other, when the button1 (btn1) is clicked make function sci_thread() start running and start thread2 that execute the main_scikit with long time code.
But tkinter keep Not Responding.
Below is my code:
import threading
class class_one:
def main_scikit(seft):
######
code_take_loooong_time
######
def save(seft):
pass
def main_form(seft):
root = Tk( )
root.minsize(width=300, height=500)
ent1 = Entry(width=30)
ent1.grid(row=0,column=1,padx = 10,pady=5)
bnt1 = Button(root,text = "Start",command=lambda : seft.sci_thread())
bnt1.grid(row=5,column=0,padx = 10)
root.update()
root.mainloop()
def sci_thread(seft):
maincal = threading.Thread(2,seft.main_scikit())
maincal.start()
co = class_one()
mainfz = threading.Thread(1,co.main_form());
mainfz.start()
Upvotes: 2
Views: 5821
Reputation: 4482
Your app is unresponsive because your target parameter executed when declared and result of that passed as target. And, obviously, because of that you GUI is unresponsive while code_take_loooong_time
being executed in GUI's thread. To deal with it - get rid of redundant parentheses.
Try this snippet:
import threading
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class class_one:
def main_scikit(self):
######
# code_take_loooong_time
# same as sleep
threading.Event().wait(5)
# some print
self.print_active_threads_count()
######
def save(self):
pass
def main_form(self):
self.root = tk.Tk()
self.root.minsize(width=300, height=500)
self.ent1 = tk.Entry(self.root, width=30)
self.ent1.grid(row=0, column=1, padx=10, pady=5)
self.bnt1 = tk.Button(self.root, text="Start", command=self.sci_thread)
self.bnt1.grid(row=5, column=0, padx=10)
self.root.update()
self.root.mainloop()
def sci_thread(self):
maincal = threading.Thread(target=self.main_scikit)
maincal.start()
def print_active_threads_count(self):
msg = 'Active threads: %d ' % threading.active_count()
self.ent1.delete(0, 'end')
self.ent1.insert(0, msg)
print(msg)
co = class_one()
mainfz = threading.Thread(target=co.main_form)
mainfz.start()
Links:
P.S.:
Also, be careful when you start a tkinter application not in the main thread because tkinter expects (in general) that mainloop
is outer-most loop possible and that all Tcl commands invoked from the same thread. So there can be many and more synchronisation problem with all that, even if you just trying to quit GUI!
In conclusion, maybe this and that would give you some new ideas.
Upvotes: 2