可能重复:
How can I monitor Tkinter buttons when Python is busy?
我写的tkinter gui代码有问题。当我按下按钮并执行该功能时它停止响应。这是一个示例代码,使事情更清晰:
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()
答案 0 :(得分:1)
这个问题是重复的,请查看原文的答案。简短回答:窗口需要运行事件循环,以便可以处理重绘事件,但是当循环运行时,事件循环将停止。
回答评论中的问题:
事件循环是一个无限循环,在您调用mainloop
时运行。它看起来像这样:
while True:
event = event_queue.pop()
event.process()
(实际上没有一个名为event_queue的全局对象,所以不要去寻找它......)
当run
正在运行时,它正在假想的event.process()
方法中运行。当您从插入文本等代码更新窗口小部件时,窗口小部件不会立即重新绘制。而是将“重绘”事件添加到队列中。但是,当您的run
函数正在运行时,您将陷入事件循环的event.process()
部分,因此不会处理其他事件。因此,在您的函数退出并且下一个事件从队列中取出之前,不会重新绘制屏幕。
现在,如果您在函数中运行update
,它将启动 new 事件循环,并处理这些事件。这可能很糟糕,因为在无限循环中有一个潜在的无限循环。但是,如果您调用update_idletasks
,则只会导致处理“空闲”任务。重绘事件属于此类别,因此会对其进行处理,但按钮点击和鼠标移动等操作未处理。