使用shutil复制文件时,Tkinter Gui会停止

时间:2016-07-26 04:35:45

标签: python tkinter

我的tkinter GUI程序运行正常,直到达到将指定文件复制到目标的功能。之后它会冻结,我无法对我的程序做任何事情,直到复制完成。它适用于小文件,但对较大的文件有害。

如何在复制文件时让GUI响应?

这是我的程序样本

from Tkinter import *

root = Tk()

def copy():
   copy(src, dst)

if something:
    copy()
else:    
   something... 

.....
....

root.mainloop()

1 个答案:

答案 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)()