我的tkinter GUI程序运行正常,直到达到将指定文件复制到目标的功能。之后它会冻结,我无法对我的程序做任何事情,直到复制完成。它适用于小文件,但对较大的文件有害。
如何在复制文件时让GUI响应?
这是我的程序样本
from Tkinter import *
root = Tk()
def copy():
copy(src, dst)
if something:
copy()
else:
something...
.....
....
root.mainloop()
答案 0 :(得分:0)
Pff,没有真正的代码很难说,但似乎你的问题是tkinter GUI通常需要运行它们的mainloop才能完全运行。 当您使用大量回调时,tkinter会停止事件循环,等待回调返回,并且文件复制是繁重且长时间的操作。
因此,解决方案是尽可能将其与mainloop分离。通常的做法是在单独的线程中生成复制操作。你可以使用_thread或threading,第二个似乎更简单:
def copy_callback(from_, to, lock):
th = threading.Thread(target=copy_thread, args=(from_, to, lock))
th.start()
def copy_thread(from_, to, lockobj):
with lockobj:
shutil.copy(from_, to)
root = tkinter.Tk()
lock = threading.Lock() # this one monitores finish of copy operation
tkinter.Button(root, text='start copy', command=lambda: copy_callback(src, dst, lock)).pack()
root.mainloop()
像这样,它不会处理复制异常(你可以根据需要添加自己的逻辑)。你应该在其他地方检查lock的状态,以表示对GUI的操作结束(例如使用tkiter方法后检查回调)
def check_callback(inst, lock, waittime):
def check():
if lock.acquire(blocking=False):
inst['text'] = 'Success!'
lock.release()
else:
inst.after(waittime, func=check)
return check
l = tkinter.Label(root, text='Copying...')
l.pack()
check_callback(l, lock, 100)()