Possible Duplicate:
How can I monitor Tkinter buttons when Python is busy?
I have a problem with tkinter gui code i wrote.It stops responding when i press a button and the function is executed.Here is an example code to make things clearer:
from Tkinter import*
import Tkinter as tk
import tkFileDialog
import urllib
import urllib2
list1 =["urls of video files"]
def run():
for links1 in list1:
text1.insert(str(list1.index(links1)+1)+'.end', 'video_'+str(list1.index(links1)+1)+'.mp4'+'.........Downloading')
text1.update()#Update text widget
urllib.urlretrieve(links1.split('\">')[0],'video_'+str(list1.index(links1)+1)+'.mp4')
text1.insert(str(list1.index(links1)+1)+'.end','.....Finished\n')
text1.yview(END)
text1.insert(END,'>>All files have been downloaded.Enjoy ! ! !\n')
#Window Title
app=Tk()
app.title("Title")
app.geometry('700x400+200+200')
app.resizable(0,0)
button=Button(app,text="Press me",font=("Times", 12, "bold"),width=20,borderwidth=5,command=run)
button.pack(padx=5,pady=8)
frame1 = Frame(app, width=600, height=200)
xframe1 = Frame(frame1, relief=RAISED, borderwidth=5)
text1 = Text(frame1,height = 3,font=("Times", 12))
text1.insert(END,"")
text1.pack(side=LEFT,fill=Y)
s_start = Scrollbar(frame1)
s_start.pack(side=RIGHT,fill=Y)
s_start.config(command=text1.yview)
text1 .config(yscrollcommand=s_start.set)
Label(frame1, text='').place(relx=1.06, rely=0.125,anchor=CENTER)
frame1.pack()
app.mainloop()
This question is a duplicate, so look at the answers for the original. Short answer: the window needs the event loop to be running so that redraw events can be processed, but while your loop is running the event loop is stopped.
To answer the question in the comments:
the event loop is an infinite loop that runs when you call
mainloop. It looks something like this:(there isn’t really a global object literally named event_queue, so don’t go looking for it…)
When
runis running, it is being run inside the imaginaryevent.process()method. When you update a widget from code such as inserting text, the widget is not immediately redrawn. Instead, a “redraw” event is added to the queue. However, while yourrunfunction is running, you are stuck in theevent.process()portion of the event loop and thus no other events are being processed. Thus, no redrawing of the screen can happen until your function exits and the next event is pulled off the queue.Now, if you run
updatein your function, it starts a new event loop and those events will be processed. This can be bad because you have a potentially infinite loop inside an infinite loop. If you callupdate_idletasks, however, it causes only the “idle” tasks to be processed. Redraw events fall into this category so they are processed, but things like button clicks and mouse movements are not processed.