-1

My tkinter GUI program runs fine until it reaches to the funtion that copies specified files to destination. After that it freezes and I can't do anything with my program until the copying finishes. It works fine for small files but irritates for larger files.

How can I make my GUI respond while copying files?

Here is my sample of program

from Tkinter import *

root = Tk()

def copy():
   copy(src, dst)

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

.....
....

root.mainloop()
Lafexlos
  • 7,618
  • 5
  • 38
  • 53
Bhuwan pandey
  • 53
  • 1
  • 2
  • 11
  • Always post your code! – Jonas Jul 26 '16 at 04:37
  • i would but its simply a funtion with no parameters having copy command from shutil. – Bhuwan pandey Jul 26 '16 at 04:40
  • Does this solve your problem: http://stackoverflow.com/questions/11756802/leave-some-code-running-while-executing-more – Jonas Jul 26 '16 at 04:42
  • i used Proecess(target=copy) ,started and join it where copy is the function that copies files but it starts again the root window.. i didnt get it all – Bhuwan pandey Jul 26 '16 at 05:07
  • 1
    Without a [mcve] it is quite hard to guess what is wrong in your program code. If you have a button, and a command handler for it, and the handler does the copying without starting a background task, the GUI will be unresponsive until that command handler returns. – J.J. Hakala Jul 26 '16 at 05:24
  • i heard of threading but dnt know to use it. can it solve my prblm n if so how to use it. plz give a example for my above sample code – Bhuwan pandey Jul 26 '16 at 05:29
  • Possible duplicate of [How do you run your own code alongside Tkinter's event loop?](http://stackoverflow.com/questions/459083/how-do-you-run-your-own-code-alongside-tkinters-event-loop) – Tadhg McDonald-Jensen Jul 26 '16 at 07:23
  • I'm sorry, that was the wrong duplicate target, [this answer](http://stackoverflow.com/a/18679229/5827215) specifically addresses a code to download a file with and without threading. – Tadhg McDonald-Jensen Jul 26 '16 at 07:27
  • thanks alot for ur effort :) – Bhuwan pandey Jul 26 '16 at 07:57

1 Answers1

1

Pff, hard to tell without real code, but it seems that your problem is that tkinter GUIs usually need their mainloop running to be fully operational. When you use a heavy callback, tkinter stops event-loop waiting for callback to return, and file copying is heavy and long-taking operation.

So the solution is to detach it from mainloop as possible. The common practice is to spawn copy operation in separate thread. You could do so with _thread or threading, the 2nd seems to be simpler:

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

Something like this, it doesn't handle copy exceptions (you could add your own logic as needed). And you should check lock's state somewhere else to signal the end of operation to GUI (for example a check callback using tkiter's after method)

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)()
thodnev
  • 1,564
  • 16
  • 20