Meter - удобный и некапризный прогрессбар+статусбар на основе Canvas. Может отображать как прогресс в процентах, так и текстовые сообщения.
meter_empty.jpg meter_processing.jpg meter_full.jpg
1 '''Michael Lange <klappnase (at) freakmail (dot) de>
2 The Meter class provides a simple progress bar widget for Tkinter.
3
4 INITIALIZATION OPTIONS:
5 The widget accepts all options of a Tkinter.Frame plus the following:
6
7 fillcolor -- the color that is used to indicate the progress of the
8 corresponding process; default is "orchid1".
9 value -- a float value between 0.0 and 1.0 (corresponding to 0% - 100%)
10 that represents the current status of the process; values higher
11 than 1.0 (lower than 0.0) are automagically set to 1.0 (0.0); default is 0.0 .
12 text -- the text that is displayed inside the widget; if set to None the widget
13 displays its value as percentage; if you don't want any text, use text="";
14 default is None.
15 font -- the font to use for the widget's text; the default is system specific.
16 textcolor -- the color to use for the widget's text; default is "black".
17
18 WIDGET METHODS:
19 All methods of a Tkinter.Frame can be used; additionally there are two widget specific methods:
20
21 get() -- returns a tuple of the form (value, text)
22 set(value, text) -- updates the widget's value and the displayed text;
23 if value is omitted it defaults to 0.0 , text defaults to None .
24 '''
25
26 import Tkinter,time
27
28 class Meter(Tkinter.Frame):
29 def __init__(self, master, height=20, bg='white', fillcolor='orchid1',\
30 value=0.0, text=None, font=None, textcolor='black', *args, **kw):
31 Tkinter.Frame.__init__(self, master, bg=bg, height=height, *args, **kw)
32 self._value = value
33
34 self._canv = Tkinter.Canvas(self, bg=self['bg'], width=self['width'], height=self['height'],\
35 highlightthickness=0, relief='flat', bd=0)
36 self._canv.pack(fill='both', expand=1)
37 self._rect = self._canv.create_rectangle(0, 0, 0, self._canv.winfo_reqheight(), fill=fillcolor,\
38 width=0)
39 self._text = self._canv.create_text(self._canv.winfo_reqwidth()/2, self._canv.winfo_reqheight()/2,\
40 text='', fill=textcolor)
41 if font:
42 self._canv.itemconfigure(self._text, font=font)
43
44 self.set(value, text)
45 self.bind('<Configure>', self._update_coords)
46
47 def _update_coords(self, event):
48 '''Updates the position of the text and rectangle inside the canvas when the size of
49 the widget gets changed.'''
50 # looks like we have to call update_idletasks() twice to make sure
51 # to get the results we expect
52 self._canv.update_idletasks()
53 self._canv.coords(self._text, self._canv.winfo_width()/2, self._canv.winfo_height()/2)
54 self._canv.coords(self._rect, 0, 0, self._canv.winfo_width()*self._value, self._canv.winfo_height())
55 self._canv.update_idletasks()
56
57 def get(self):
58 return self._value, self._canv.itemcget(self._text, 'text')
59
60 def set(self, value=0.0, text=None):
61 #make the value failsafe:
62 if value < 0.0:
63 value = 0.0
64 elif value > 1.0:
65 value = 1.0
66 self._value = value
67 if text == None:
68 #if no text is specified use the default percentage string:
69 text = str(int(round(100 * value))) + ' %'
70 self._canv.coords(self._rect, 0, 0, self._canv.winfo_width()*value, self._canv.winfo_height())
71 self._canv.itemconfigure(self._text, text=text)
72 self._canv.update_idletasks()
73
74 def fill():
75 for i in range(100):
76 time.sleep(0.1)
77 meter.set(float(i)/100)
78 #tk.update_idletasks()
79 meter.set(1,"Завершено")
80
81 if __name__ == '__main__':
82 tk = Tkinter.Tk()
83 Tkinter.Button(text='Заполнить',command=fill).pack()
84 meter = Meter(tk,width=200)
85 meter.pack()
86 meter.set(0,"Ожидание...")
87
88 tk.mainloop()