Hi I have a small python gui interface with two buttons, start(That starts a counter) and stop (that is suppose to stop the counter), the counter is an infinite loop since I do not want it to end unless the second button is clicked. The problem is the second button cannot be clicked while the function from the first one is still running.
I read that I need to use threading and I have tried but I do not fully understand how I can do this. Please help.
from Tkinter import *
for _ in range(10):
for i in itertools.count(1, 1):
m = Threader(name="main")
o = Threader(name="other")
'''From here on we are building the Gui'''
root = Tk()
'''Lets build the GUI'''
'''We need two frames to help sort shit, a left and a right vertical frame'''
leftFrame = Frame(root)
rightFrame = Frame(root)
playButton = Button(leftFrame, text="Play", fg="blue", command=m.main)
stopButton = Button(rightFrame, text="Stop", fg="red", command=o.other)
except Exception, e:
Here's a short example of using
threading. I took out your
other function and I don't know why your using
itertools here. I took that out as well and simply setup using a simple threading example.
A few things:
You setup using
threading.Thread as the base class for
Threader, but you never actually initialized the base class.
Whenever you use threading you generally want to define a
run method and then use
start() to start the thread. Calling
start() will call
You need to use threading to prevent your GUI blocking, because tkinter is just one thread on a giant loop. So, whenever you have some long running process it blocks this thread until the current process is complete. That's why it's put in another thread. Python has something called the GIL, which prevent's true parallelization (I made up that word) since it only one thread can ever be used at a time. Instead, it uses time slicing, the GIL sort of "polls" between them to give the appearance of multiple tasks running concurrently. For true parallel processing you should use
In the below code I have used
self.daemon = True. Setting the thread to be a daemon will kill it when you exit the main program (In this case the Tk GUI)
from tkinter import * import threading, time class Threader(threading.Thread): def __init__(self, *args, **kwargs): threading.Thread.__init__(self, *args, **kwargs) self.daemon = True self.start() def run(self): while True: print("Look a while true loop that doesn't block the GUI!") print("Current Thread: %s" % self.name) time.sleep(1) if __name__ == '__main__': root = Tk() leftFrame = Frame(root) leftFrame.pack(side=LEFT) rightFrame = Frame(root) rightFrame.pack(side=RIGHT) playButton = Button(leftFrame, text="Play", fg="blue", command= lambda: Threader(name='Play-Thread')) stopButton = Button(rightFrame, text="Stop", fg="red", command= lambda: Threader(name='Stop-Thread')) playButton.pack(side=TOP) stopButton.pack(side=BOTTOM) root.mainloop()