From: Tom A. <TA...@OR...> - 2008-11-13 13:06:54
|
I've written a program to where you enter a URL of a file to download. When downloads the file and displays the progress with the Gauge widget and displays the download speed. When the file is being downloaded I am unable to use any buttons or type any text in the window. One the download is complete the program responds the way it should. How do you place the download process in the background and still have the progress and speed still displayed? I may be in a brain lock, but I can not figure it out. import urllib2, sre, sys, time, urllib from PythonCard import model class Main(model.Background): global timer global speed timer = 0 speed = '' def on_initialize(self, event): self.components.progressBar.value = timer self.components.speedField.text = speed def on_progressBar_timer(self, event, timer): self.components.progressBar.value = timer def on_getBtn_mouseClick(self,event): file_url = self.components.fileURLInput.text lastUpdate = 0.0 progressSize = 0 def reportHook(count, blocksize, totalsize): global lastUpdate global progressSize global timer global speed if count == 0: lastUpdate = time.time() progressSize = 0 return progressSize += blocksize deltaTime = time.time() - lastUpdate if deltaTime > .1: percent = int(float(count * blocksize * 100) / totalsize) speed = int(progressSize / (1024 * deltaTime)) timer = int(percent) speed = str(speed) speed = speed + ' kbs' self.components.progressBar.value = int(timer) self.components.speedField.text = str(speed) lastUpdate = time.time() progressSize = 0 def getName(file_url): # Get file name from URL farray = file_url.split('/') flen = len(farray) flen = flen - 1 return farray[flen] def dlFile(file_url, file_name): urllib.urlretrieve(file_url,file_name,reportHook) print 'Done' timer = 0 speed = '' self.components.progressBar.value = timer self.components.speedField.text = speed def mainDL(file_url): file_name = getName(file_url) dlFile(file_url,file_name) mainDL(file_url) def on_exitBtn_mouseClick(self, event): sys.exit(0) if __name__ == '__main__': app = model.Application(Main) app.MainLoop() |
From: Aaron S. <az...@bu...> - 2008-11-13 18:12:19
|
Hi Tom, What you need is to use multi-threading. If you are not familiar with multi-threading, basically a thread is a stream of execution within your program. The "main" thread is blocking while reading the file. That's why it seems unresponsive -- it keeps waiting for data, but it cannot respond to the user interface until it is done with the download. A good design would be to create a separate worker thread to handle the download, and then have your method (in the main thread) launch the worker thread, and then return from the method so the UI can respond to other user requests. The worker thread would continue until the file is complete, and then exit. You can read about threading here: http://www.python.org/doc/2.5.2/lib/module-thread.html Basically, you start up a thread and give it a function to execute. When the function ends, the thread ends with it. You will need to use some coordination to make it possible for the "main" thread to read status from the worker thread, to know its progress. I would recommend a "push" model, whereby the worker thread pushes its status to the main GUI. This could be as simple as having it write to: self.components.progressBar.value = int(timer) So long as NO OTHER CODE writes to that progress bar's value. If any other code might also write to it, you will need to protect it using the LockType object described in the API page. I hope this helps! Best, Aaron On Nov 13, 2008, at 7:30 AM, Tom Angle wrote: > I've written a program to where you enter a URL of a file to > download. When downloads the file and displays the progress with the > Gauge widget and displays the download speed. When the file is being > downloaded I am unable to use any buttons or type any text in the > window. One the download is complete the program responds the way it > should. How do you place the download process in the background and > still have the progress and speed still displayed? I may be in a > brain lock, but I can not figure it out. > > import urllib2, sre, sys, time, urllib > from PythonCard import model > > class Main(model.Background): > > global timer > global speed > timer = 0 > speed = '' > > def on_initialize(self, event): > self.components.progressBar.value = timer > self.components.speedField.text = speed > > def on_progressBar_timer(self, event, timer): > self.components.progressBar.value = timer > > def on_getBtn_mouseClick(self,event): > file_url = self.components.fileURLInput.text > > lastUpdate = 0.0 > progressSize = 0 > > def reportHook(count, blocksize, totalsize): > global lastUpdate > global progressSize > global timer > global speed > > if count == 0: > lastUpdate = time.time() > progressSize = 0 > return > > progressSize += blocksize > deltaTime = time.time() - lastUpdate > > if deltaTime > .1: > percent = int(float(count * blocksize * 100) / > totalsize) > speed = int(progressSize / (1024 * deltaTime)) > timer = int(percent) > speed = str(speed) > speed = speed + ' kbs' > self.components.progressBar.value = int(timer) > self.components.speedField.text = str(speed) > lastUpdate = time.time() > progressSize = 0 > > def getName(file_url): > # Get file name from URL > farray = file_url.split('/') > flen = len(farray) > flen = flen - 1 > return farray[flen] > > def dlFile(file_url, file_name): > urllib.urlretrieve(file_url,file_name,reportHook) > print 'Done' > timer = 0 > speed = '' > self.components.progressBar.value = timer > self.components.speedField.text = speed > > def mainDL(file_url): > file_name = getName(file_url) > dlFile(file_url,file_name) > > mainDL(file_url) > > def on_exitBtn_mouseClick(self, event): > sys.exit(0) > > if __name__ == '__main__': > app = model.Application(Main) > app.MainLoop() > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's > challenge > Build the coolest Linux based applications with Moblin SDK & win > great prizes > Grand prize is a trip for two to an Open Source event anywhere in > the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/_______________________________________________ > Pythoncard-users mailing list > Pyt...@li... > https://lists.sourceforge.net/lists/listinfo/pythoncard-users |
From: Nextime <ne...@ne...> - 2008-11-13 21:22:15
|
On Thu, Nov 13, 2008 at 06:30:08AM -0600, Tom Angle wrote: --SNIP-- > How do you > place the download process in the background and still have the progress > and speed still displayed? I may be in a brain lock, but I can not > figure it out. --SNIP-- You can use a thread, a subprocess, or something like twisted and deferreds -- Franco Lanza My blog: http://www.nexlab.it email: ne...@ne... Fax/Tel: +39 0331 682151 Cell: +39 339 8125940 Busto Arsizio (VA) - Italy ----------------------------------- NO TCPA: http://www.no1984.org you can download my public key at: http://danex.nexlab.it/nextime.asc || Key Servers Key ID = D6132D50 Key fingerprint = 66ED 5211 9D59 DA53 1DF7 4189 DFED F580 D613 2D50 ----------------------------------- echo 16i[q]sa[ln0=aln100%Pln100/snlbx]sbA0D212153574F444E49572045535520454D20454B414D204F54204847554F4E452059415020544F4E4E4143205345544147204C4C4942snlbxq | dc ----------------------------------- |