""" I needed a simple gauge, so I've made on with Pmw. It might be useful for others to use as a base to develop more comples gauges with. Is it worth cleaning up and submitting? cheers and thanks chris Dr. Chris Wright Intensive Care Unit Monash Medical Centre Clayton. VIC Australia """ import sys import Tkinter import Pmw import time if sys.platform == 'win32': # MS-Windows specific fonts label_font = "-family Ariel -size 12" value_font = "-family Ariel -size 12" small_font = "-family {MS Sans Serif} -size 9 -weight bold" header_font = "-family {MS Sans Serif} -weight bold" else: # X-Windows specific fonts label_font = "-*-helvetica-*-r-*-*-*-160-*-*-*-*-*-*" value_font = "-*-courier-*-r-*-*-*-160-*-*-*-*-*-*" small_font = "-*-helvetica-*-r-*-*-*-130-*-*-*-*-*-*" header_font = "-*-helvetica-bold-r-*-*-*-150-*-*-*-*-*-*" class VerticalGauge(Pmw.MegaWidget): """Vertical gauge with actual and desired settings""" def __init__(self, parent = None, **kw): optiondefs = ( ('min', 0, None), ('max', 100, None), ('majortickinterval', 10, None), ('minortickinterval', 5, None), ('units', '', None), ('bg', 'grey', self._backgroundSet), ('actualvalue', 50, self._actualSet), ('desiredvalue', 50, self._desiredSet), ('actualcolour', 'yellow1', None), ('desiredcolour', 'turquoise1', None), ('label', 'Label', None), ) self.defineoptions(kw, optiondefs) Pmw.MegaWidget.__init__(self, parent) interior = self.interior() interior.grid_rowconfigure(1, weight = 1) for r in range(3): interior.grid_columnconfigure(r, weight = 1) self.actuallabel = self.createcomponent('actualLabel', (), None, Tkinter.Label, (interior,), text = '', width = 3, relief = 'sunken', bd = 1, fg = self['actualcolour'], font = value_font) self.actuallabel.grid(sticky = "nswe", row = 0, column = 0) self.label = self.createcomponent('label', (), None, Tkinter.Label, (interior,), text = self['label'], relief = 'raised', font = label_font, fg = 'navy', bd = 2) self.label.grid(sticky = "nsew", row = 0, column = 1) self.desiredlabel = self.createcomponent('desiredLabel', (), None, Tkinter.Label, (interior,), text = '', width = 3, relief = 'sunken', bd = 1, fg = self['desiredcolour'], font = value_font) self.desiredlabel.grid(sticky = "nswe", row = 0, column = 2) self.canvas = self.createcomponent('canvas', (), None, Tkinter.Canvas, (interior,), width = 100, height = 300, bg = 'grey') self.canvas.grid(sticky = "nsew", columnspan = 3, pady = 1) self.canvas.bind("", self._createGaugeAxes) self._createGaugeAxes() self.initialiseoptions() def _createGaugeAxes(self, event = None): min = self['min'] max = self['max'] units = self['units'] majortickinterval = self['majortickinterval'] gauge_range = max - min c = self.canvas c.delete("all") if event: h, w = event.height, event.width else: h = int(c.configure("height")[4]) w = int(c.configure("width")[4]) self.lower = h - 15 self.upper = 15 self.middle = w / 2 c.create_line(self.middle, self.lower, self.middle, self.upper) majortickcount = int((max - min) / majortickinterval) self.axislength = self.lower - self.upper self.majortickdistance = float(self.axislength) / majortickcount self.majortickwidth = w / 5 labeloffset = (w / 4) + 10 for i in range(majortickcount + 1): v = min + i * majortickinterval d = self.lower - i * self.majortickdistance c.create_line(self.middle, d, self.middle + self.majortickwidth, d) c.create_text(self.middle + labeloffset, d, font = small_font, text = str(v)) self._desiredSet(event) self._actualSet(event) def _backgroundSet(self): self.canvas.configure(bg = self['bg']) def _desiredSet(self, event = None): c = self.canvas desired = self['desiredvalue'] desiredcolour = self['desiredcolour'] min = self['min'] max = self['max'] if desired > max: desired = max if desired < min: desired = min gauge_range = max - min c = self.canvas if event: h, w = event.height, event.width else: h = int(c.configure("height")[4]) w = int(c.configure("width")[4]) desired_y = self.lower - (float(desired - min) / gauge_range) * self.axislength try: c.delete('desiredBar') except: pass c.create_line(self.middle - self.majortickwidth, desired_y, self.middle + self.majortickwidth, desired_y, fill = desiredcolour, stipple = 'gray50', width = 10, tag = 'desiredBar') self.desiredlabel.configure(text = desired) def setActual(self, value): self.configure(actualvalue = value) def getActual(self): return self.cget('actualvalue') def _actualSet(self, event = None): c = self.canvas actual = self['actualvalue'] actualcolour = self['actualcolour'] min = self['min'] max = self['max'] if actual > max: actual = max if actual < min: actual = min gauge_range = max - min c = self.canvas if event: h, w = event.height, event.width else: h = int(c.configure("height")[4]) w = int(c.configure("width")[4]) actual_y = self.lower - (float(actual - min) / gauge_range) * self.axislength try: c.delete('actualPointer') except: pass triangle = ((self.middle, actual_y), (self.middle - 1.4 * self.majortickwidth, actual_y - self.majortickwidth / 2), (self.middle - 1.4 * self.majortickwidth, actual_y + self.majortickwidth / 2)) c.create_polygon(triangle, fill = actualcolour, tag = 'actualPointer') self.actuallabel.configure(text = actual) Pmw.forwardmethods(VerticalGauge, Tkinter.Canvas, 'canvas') if __name__ == '__main__': # Initialise Tkinter and Pmw. root = Pmw.initialise() root.title('Pmw VerticalGauge demonstration') def increase(): av = g1.getActual() g1.setActual(av + 1) def decrease(): av = g1.getActual() g1.setActual(av - 1) g1 = VerticalGauge(min = 0, max = 30, actualvalue = 15, desiredvalue = 22, majortickinterval = 2, label = "Pms") g1.grid(sticky = "nsew") root.grid_rowconfigure(0, weight = 1) root.grid_columnconfigure(0, weight = 1) b1 = Tkinter.Button(text = "Increase", command = increase) b1.grid() b2 = Tkinter.Button(text = "Decrease", command = decrease) b2.grid() # Let's go. root.mainloop()