Hi all, I don't really understand how to properly use threading in my programs, however I have managed to get by so far using them improperly. Once again I have come up to what I think is something that won't work because of the way the program is set up.
I have a long running process running underneath a gui in a different thread, and a progress bar that updates the status of the operation. What I would like to do is use something like : self.progressWindow.protocol('WM_DELETE_WINDOW', self.callback) and setup the callback to kill the operation and then the window when the user clicks on the X of the progress window. I've implemented this in my code, but clicking on the X does nothing until I kill the main thread (i think), and then my callback is run. I've also had problems in the past of the gui not refreshing properly, which leads me to believe that both of these are thread related. Any help would be immensely appreciated. ~Sean DiZazzo ~~~~~~~~~~~~~~~~~~~ import sys, os, time libdir = "/usr/local/sw/lib" sys.path.append(libdir) import ProgressBarView, Folder, P from Tkinter import * from tkFileDialog import askopenfilenames from tkMessageBox import showerror, showinfo import pexpect, ssh_session import P import Pmw rootWin = Tk() class Window(Frame): label = None initialdir = "/" dest = "/tmp" folder = None logpath = "/tmp/Send.log" copyindex = 0 files = [] progressWindow = None session = None password = P.P() ssh = ssh_session.ssh_session("root", "XX.XX.XX.XX", password.Decrypt(password.sean)) timeout = 30 def __init__(self, parent=None): Frame.__init__(self, parent) rootWin.title("Send to Blah") rootWin.resizable(width=0,height=0) self.pack() self.progress_and_log() f = Frame(self) openfunc = (lambda self=self, name=None: self.openfolder()) Button(f, text="Choose", command=openfunc).pack(side="left") self.label = Label(f, text=' <--- Choose files', bg="grey", width=40, justify='left', anchor='w') self.label.pack(side="left", anchor='w', padx=5) f.pack(padx=10, pady=10, side='left', fill='both', anchor='w') submitfunc = (lambda self=self, name=None: self.submit()) b = Button(self, text="Send", command=submitfunc) b.pack(side="right", padx=5) def openfolder(self): self.files = [] self.files_tuple = askopenfilenames(parent=rootWin, initialdir="/") for file in self.files_tuple: self.files.append(file) self.files.sort() label = "Click button to send files -->" self.st.configure(text_state = 'normal') self.st.clear() self.st.insert('end', "Files to be copied:\n") self.st.insert('end', "~~~~~~~~~~~~~~~~~~~\n") for file in self.files: self.st.insert('end', os.path.split(file)[-1] + "\n") self.st.insert('end', " \n \n") self.st.configure(text_state = 'disabled') self.label.config(text='Click to send files ---> ', justify='right', anchor='e') def callback(self): """Need to get the pid here and kill the running process""" def submit(self): files = self.files dest = Folder.Folder(self.dest) for file in files: if self.ssh.exists(os.path.join(dest.path, os.path.split(file)[-1])): showerror("error", "The file '%s' already exists" % os.path.join(dest.path, os.path.split(file)[-1])) return 0 import threading geometry = None for file in files: self.progressWindow = Toplevel(rootWin) self.progressWindow.protocol('WM_DELETE_WINDOW', self.callback) self.progressWindow.geometry(geometry) self.progressWindow.title("Progress") self.progressWindow.resizable(width=0,height=0) self.proglabel = Label(self.progressWindow, text='Copying...', anchor=NW, justify=LEFT, width=30) self.proglabel.pack(fill=X, expand=1) self.progressBar = ProgressBarView.ProgressBarView(self.progressWindow) self.progressBar.pack(fill=X) threading.Thread(target=self.threadedCopy,args=(file, dest)).start() #grab the location from the first window if geometry is None: self.progressBar.updateProgress(0) geometry = self.progressWindow.geometry() self.incrementProgress(self.progressWindow, file, dest) self.label.config(text=" <--- Choose files", justify='left', anchor='w') self.files=[] def progress_and_log(self): self.st = Pmw.ScrolledText(rootWin, borderframe = 1, usehullsize = 1, hull_width = 400, hull_height = 150, text_wrap='none', #text_font = fixedFont, text_padx = 4, text_pady = 4, ) self.st.configure(text_state = 'disabled') self.st.pack(padx = 5, pady = 5, fill = 'both', expand = 1) def threadedCopy(self, file, dest): self.ssh.scp(file, os.path.join(dest.path, os.path.split(file)[1])) def appendToLog(self, src, dest): dest_size = self.ssh.size(dest.path) try: dest_size = float(dest_size) except: dest_size = 0 if src.size == dest_size: status = "SUCCESS" else: status = "FAILED" entry = "%s - %s %s, %s\n" % (time.ctime(time.time()), status, src.name, src.readableSize) f = open(self.logpath, 'a') f.write(entry) f.close() self.st.configure(text_state = 'normal') self.st.insert('end', entry) self.st.configure(text_state = 'disabled') def incrementProgress(self, window, file, dest): import File src = File.File(file) dest = File.File(os.path.join(dest.path, os.path.split(file)[-1])) start = time.time() p = 0 last_dest = 0 same_count = 0 while p < 100: d_size = self.ssh.size(dest.path) try: float(d_size) except: "Couldn't turn %s into a float" % d_size continue if last_dest == d_size and same_count == 40: showerror("error", "Error copying %s\nRemoving the partially transferred file and continuing..." % dest.path) self.ssh.ssh("sudo rm %s" % dest.path) if d_size == None: d_size = 1000 self.proglabel.config(text=src.name) p = (float(d_size) / float(src.size)) * 100.0 d_size = self.ssh.size(dest.path) if last_dest == d_size: same_count = same_count +1 print "P:", p self.progressBar.updateProgress(p) self.update_idletasks() time.sleep(0.25) last_dest = d_size self.appendToLog(src, dest) window.destroy() return if __name__ == "__main__": Window().mainloop() -- http://mail.python.org/mailman/listinfo/python-list