253 lines
6.4 KiB
Python
253 lines
6.4 KiB
Python
"""
|
|
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("<Configure>", 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()
|