Baby Language Lab Scripts
A collection of data processing tools.
 All Classes Namespaces Files Functions Variables Pages
progress_dialog.py
Go to the documentation of this file.
1 ## @package utils.progress_dialog
2 
3 from gi.repository import Gtk as gtk
4 
5 ## A popup dialog box that displays a progress bar.
6 #
7 # Progress bars go through one or more "phases". In each phase, a different string is displayed in the middle of the bar.
8 # This allows you to tell the user something about what is being done while they're waiting. You can set up the phases
9 # by passing a list of strings to the constructor. You can move through them using the next_phase() method.
10 # The progress bar's "fill level" (a float value in [0.0, 1.0])can be updated by calling the set_fraction() method. This advances the fill level to
11 # a given proportion of completeness <em>for the current phase</em>.
12 #
13 # For example, if your progress bar has only one phase, calling set_fraction(0.5) will advance the fill level to the halfway fill point.
14 # On the other hand if the progress bar has two phases, and we are in phase 1, then calling set_fraction(0.5) will advance the fill level to half of phase one (the one quarter fill point).
15 # Subsequently calling next_phase() advances to phase 2. Here, calling set_fraction(0.5) will advance the fill level to half of phase two (the three-quarter fill point).
16 #
17 # When the progress bar reaches a fill level of 1.0 (or higher), the dialog box automatically closes.
18 #
19 # To ensure that progress bars don't get left lying around if something goes wrong (like an exception in the processing code that prevents an update of the fill level, or a round-off error in your fill level calculations that results in a
20 # maximum fill level of something like 0.99), you should always call ensure_finish() when you are done your processing (or in your exception handling code). This will force the dialog to close if it's still around.
21 # Note that instantiating this class does not show the progress dialog - you must call the show() method (inherited from gtk.Dialog) when you want that to happen.
22 class ProgressDialog(gtk.Dialog):
23  ## Constructor
24  # @param self
25  # @param title (string=None) string to display in the titlebar of the dialog
26  # @param phases (list=['']) list of strings, one for each phase
27  # @param parent (gtk widget) the dialog's temporary parent, or None. This allows you to link the dialog together with its parent and do things like have them destroyed at the same time - see superclass description (gtk docs for gtk.Dialog) for details.
28  # @param flags (int=0) gtk flags to control how the dialog works - see superclass description (gtk docs for gtk.Dialog) for available options here.
29  # @param buttons (tuple=None) a tuple of button text/response code pairs for buttons to create in this dialog, or None - see superclass description (gtk docs for gtk.Dialog).
30  def __init__(self, title=None, phases=[''], parent=None, flags=0, buttons=None):
31  gtk.Dialog.__init__(self, title, parent, flags, buttons)
32  self.phases = phases
33  self.cur_phase = 0
34 
35  self.pb = gtk.ProgressBar()
36  self.pb.set_show_text(True)
37  self.pb.set_orientation(gtk.Orientation.HORIZONTAL)
38  self.pb.set_fraction(0.0)
39  self.pb.set_text(self.phases[self.cur_phase])
40 
41  content_box = self.get_content_area()
42  content_box.pack_start(self.pb, True, True, 0)
43  self.pb.show()
44  content_box.show()
45  #leave the responsibility of showing the dialog itself up to the caller
46 
47  ## Sets the "fill level" of the progress bar. See this class' description for details about how this is done.
48  # @param self
49  # @param fraction (float) a float value in the range [0.0, 1.0]. This will set the fill level to (phase / num_phases + fraction / num_phases).
50  # In other words, it sets the current phase's fill level. To completely fill the progress bar, you must move through the phases (using next_phase()), increasing the fill level to 1.0 in each of them.
51  def set_fraction(self, fraction):
52  self.pb.set_fraction(float(self.cur_phase) / float(len(self.phases)) + float(fraction) / float(len(self.phases)))
53  #this forces gtk to process all pending UI updates (without it, the progress bar remains uninitialized until processing is complete - then it displays 100% completion...
54  while gtk.events_pending():
55  #gtk.main_iteration(False)
56  gtk.main_iteration()
57 
58  #kill the dialog when we reach 100% completion
59  if self.pb.get_fraction() >= 1.0:
60  self.destroy()
61 
62  ## Move the progress dialog to the next phase. See this class' description for more info on "phases". Moving to the next phase will update the text in the center of the progress bar
63  # to the next value in the "phases" list that was passed to the constructor.
64  # @param self
65  def next_phase(self):
66  self.cur_phase += 1
67  self.pb.set_text(self.phases[self.cur_phase])
68  while gtk.events_pending():
69  #gtk.main_iteration(False)
70  gtk.main_iteration()
71 
72  ## Returns the current fill level (absolute fill level, not the fill level of the current phase) of the progress bar, as a float.
73  # @returns (float) a number in the range [0.0, 1.0]
74  def get_fraction(self):
75  return self.pb.get_fraction()
76 
77  ## If the progress bar is not at 100% completion, this method will move it there, which closes the dialog.
78  def ensure_finish(self):
79  if self.pb.get_fraction() < 1.0:
80  self.set_fraction(1.0)