471,330 Members | 1,771 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,330 software developers and data experts.

Making a Progress Bar work with a subprocess

How can I make a Progress Bar in Python (GTK+) work together with a subprocess (lets say....youtube-dl or wget )?
Oct 5 '07 #1
1 6843
I was just struggling with this myself, so I happen to have example code for a progressbar. In my case the subprocess is run as a thread within the same program, which makes knowing the relative progress of the work easier.

Expand|Select|Wrap|Line Numbers
  1. import gobject
  2. import gtk
  3. import threading
  4. import time
  5.  
  6. class TestThread(threading.Thread):
  7.     def __init__(self, mainview):
  8.         threading.Thread.__init__(self)
  9.         self.mainview = mainview
  10.  
  11.     def run(self):
  12.         self.work_complete = False
  13.         self.amount_completed = 0
  14.         gobject.timeout_add(100, self._update_bar)
  15.  
  16.         for i in range(10):
  17.             time.sleep(0.3)
  18.             self.amount_completed += .1
  19.  
  20.         self.work_complete = True
  21.  
  22.     def _update_bar(self):
  23.         self.mainview.progressbar.set_fraction(self.amount_completed)
  24.         if self.work_complete:
  25.             self.mainview.progressbar.set_text("Complete!")
  26.         else:
  27.             self.mainview.progressbar.set_text("%d%%" % (self.amount_completed * 100))            
  28.         return not self.work_complete
  29.  
  30. class MainView(gtk.Window):
  31.     def __init__(self):
  32.         gtk.Window.__init__(self)
  33.         self.connect('delete_event', self.handle_window_delete_event)
  34.         self.connect('destroy', self.quit)
  35.  
  36.         self.progressbar = gtk.ProgressBar()
  37.         button1 = gtk.Button("Test")
  38.         button1.connect('clicked', self.button1_click)
  39.         box = gtk.VBox()
  40.         box.pack_start(self.progressbar)
  41.         box.pack_start(button1)
  42.         self.add(box)
  43.  
  44.     def quit(self, *args):
  45.         gtk.main_quit()
  46.  
  47.     def handle_window_delete_event(self, *args):
  48.         return False
  49.  
  50.     def button1_click(self, *args):
  51.         self.progressbar.set_fraction(0)
  52.         worker = TestThread(self)
  53.         worker.start()
  54.  
  55. if __name__ == "__main__":
  56.     gobject.threads_init()
  57.     MainView().show_all()
  58.     gtk.main()
  59.  
Here's a summary of the important aspects:
  • gobject.threads_init() must be called if the application will use other threads
  • The TestThread.run() method is run its own thread and it's not recommended to manipulate widgets directly from there.
  • The TestThread.run() uses gobject.timeout_add() to register a callback method, which will be allowed to freely manipulate widgets and other GTK elements. The method will be called automatically with 100 millisecond intervalls. By returning False the callback method will be disabled.
  • Obviously you have to have some way to measure the overall progress to show relevant "percent completed" info. You should calculate the fraction of downloaded bytes per total amount of bytes and assign it to the ProgressBar using ProgressBar.set_fraction(). If you cant know the relative progress I suggest you show a pendling progress bar without percentage info until the download hads completed.

I verified that the ProgressBar may be manipulated directly from the TestThread. However, I have had problems (segfaults, deadlocks, etc.) if widget manipulations have been performed from other threads than the GTK main thread.
Oct 5 '07 #2

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

reply views Thread by Miki Tebeka | last post: by
reply views Thread by Roman Neuhauser | last post: by
4 posts views Thread by Marc Carter | last post: by
2 posts views Thread by Stewart Midwinter | last post: by
3 posts views Thread by Darren Dale | last post: by
3 posts views Thread by madpython | last post: by
5 posts views Thread by Cameron Laird | last post: by
9 posts views Thread by Phoe6 | last post: by
12 posts views Thread by bhunter | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.