Meter - удобный и некапризный прогрессбар+статусбар на основе Canvas. Может отображать как прогресс в процентах, так и текстовые сообщения. [[attachment:meter_empty.jpg]] [[attachment:meter_processing.jpg]] [[attachment:meter_full.jpg]] {{{#!highlight python '''Michael Lange The Meter class provides a simple progress bar widget for Tkinter. INITIALIZATION OPTIONS: The widget accepts all options of a Tkinter.Frame plus the following: fillcolor -- the color that is used to indicate the progress of the corresponding process; default is "orchid1". value -- a float value between 0.0 and 1.0 (corresponding to 0% - 100%) that represents the current status of the process; values higher than 1.0 (lower than 0.0) are automagically set to 1.0 (0.0); default is 0.0 . text -- the text that is displayed inside the widget; if set to None the widget displays its value as percentage; if you don't want any text, use text=""; default is None. font -- the font to use for the widget's text; the default is system specific. textcolor -- the color to use for the widget's text; default is "black". WIDGET METHODS: All methods of a Tkinter.Frame can be used; additionally there are two widget specific methods: get() -- returns a tuple of the form (value, text) set(value, text) -- updates the widget's value and the displayed text; if value is omitted it defaults to 0.0 , text defaults to None . ''' import Tkinter,time class Meter(Tkinter.Frame): def __init__(self, master, height=20, bg='white', fillcolor='orchid1',\ value=0.0, text=None, font=None, textcolor='black', *args, **kw): Tkinter.Frame.__init__(self, master, bg=bg, height=height, *args, **kw) self._value = value self._canv = Tkinter.Canvas(self, bg=self['bg'], width=self['width'], height=self['height'],\ highlightthickness=0, relief='flat', bd=0) self._canv.pack(fill='both', expand=1) self._rect = self._canv.create_rectangle(0, 0, 0, self._canv.winfo_reqheight(), fill=fillcolor,\ width=0) self._text = self._canv.create_text(self._canv.winfo_reqwidth()/2, self._canv.winfo_reqheight()/2,\ text='', fill=textcolor) if font: self._canv.itemconfigure(self._text, font=font) self.set(value, text) self.bind('', self._update_coords) def _update_coords(self, event): '''Updates the position of the text and rectangle inside the canvas when the size of the widget gets changed.''' # looks like we have to call update_idletasks() twice to make sure # to get the results we expect self._canv.update_idletasks() self._canv.coords(self._text, self._canv.winfo_width()/2, self._canv.winfo_height()/2) self._canv.coords(self._rect, 0, 0, self._canv.winfo_width()*self._value, self._canv.winfo_height()) self._canv.update_idletasks() def get(self): return self._value, self._canv.itemcget(self._text, 'text') def set(self, value=0.0, text=None): #make the value failsafe: if value < 0.0: value = 0.0 elif value > 1.0: value = 1.0 self._value = value if text == None: #if no text is specified use the default percentage string: text = str(int(round(100 * value))) + ' %' self._canv.coords(self._rect, 0, 0, self._canv.winfo_width()*value, self._canv.winfo_height()) self._canv.itemconfigure(self._text, text=text) self._canv.update_idletasks() def fill(): for i in range(100): time.sleep(0.1) meter.set(float(i)/100) #tk.update_idletasks() meter.set(1,"Завершено") if __name__ == '__main__': tk = Tkinter.Tk() Tkinter.Button(text='Заполнить',command=fill).pack() meter = Meter(tk,width=200) meter.pack() meter.set(0,"Ожидание...") tk.mainloop() }}}