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

Reply via email to