Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | """ |
2 | I needed a simple gauge, so I've made on with Pmw. | |
3 | It might be useful for others to use as a base to develop more comples | |
4 | gauges with. | |
5 | ||
6 | Is it worth cleaning up and submitting? | |
7 | ||
8 | cheers and thanks | |
9 | ||
10 | chris | |
11 | ||
12 | Dr. Chris Wright | |
13 | Intensive Care Unit | |
14 | Monash Medical Centre | |
15 | Clayton. VIC Australia | |
16 | """ | |
17 | ||
18 | import sys | |
19 | import Tkinter | |
20 | import Pmw | |
21 | import time | |
22 | ||
23 | ||
24 | if sys.platform == 'win32': | |
25 | # MS-Windows specific fonts | |
26 | label_font = "-family Ariel -size 12" | |
27 | value_font = "-family Ariel -size 12" | |
28 | small_font = "-family {MS Sans Serif} -size 9 -weight bold" | |
29 | header_font = "-family {MS Sans Serif} -weight bold" | |
30 | else: | |
31 | # X-Windows specific fonts | |
32 | label_font = "-*-helvetica-*-r-*-*-*-160-*-*-*-*-*-*" | |
33 | value_font = "-*-courier-*-r-*-*-*-160-*-*-*-*-*-*" | |
34 | small_font = "-*-helvetica-*-r-*-*-*-130-*-*-*-*-*-*" | |
35 | header_font = "-*-helvetica-bold-r-*-*-*-150-*-*-*-*-*-*" | |
36 | ||
37 | class VerticalGauge(Pmw.MegaWidget): | |
38 | """Vertical gauge with actual and desired settings""" | |
39 | ||
40 | def __init__(self, parent = None, **kw): | |
41 | optiondefs = ( | |
42 | ('min', 0, None), | |
43 | ('max', 100, None), | |
44 | ('majortickinterval', 10, None), | |
45 | ('minortickinterval', 5, None), | |
46 | ('units', '', None), | |
47 | ('bg', 'grey', self._backgroundSet), | |
48 | ('actualvalue', 50, self._actualSet), | |
49 | ('desiredvalue', 50, self._desiredSet), | |
50 | ('actualcolour', 'yellow1', None), | |
51 | ('desiredcolour', 'turquoise1', None), | |
52 | ('label', 'Label', None), | |
53 | ) | |
54 | self.defineoptions(kw, optiondefs) | |
55 | Pmw.MegaWidget.__init__(self, parent) | |
56 | ||
57 | interior = self.interior() | |
58 | interior.grid_rowconfigure(1, weight = 1) | |
59 | for r in range(3): | |
60 | interior.grid_columnconfigure(r, weight = 1) | |
61 | ||
62 | self.actuallabel = self.createcomponent('actualLabel', | |
63 | (), None, | |
64 | Tkinter.Label, (interior,), | |
65 | text = '', | |
66 | width = 3, | |
67 | relief = 'sunken', | |
68 | bd = 1, | |
69 | fg = self['actualcolour'], | |
70 | font = value_font) | |
71 | self.actuallabel.grid(sticky = "nswe", row = 0, column = 0) | |
72 | ||
73 | self.label = self.createcomponent('label', | |
74 | (), None, | |
75 | Tkinter.Label, (interior,), | |
76 | text = self['label'], | |
77 | relief = 'raised', | |
78 | font = label_font, | |
79 | fg = 'navy', | |
80 | bd = 2) | |
81 | self.label.grid(sticky = "nsew", row = 0, column = 1) | |
82 | ||
83 | self.desiredlabel = self.createcomponent('desiredLabel', | |
84 | (), None, | |
85 | Tkinter.Label, (interior,), | |
86 | text = '', | |
87 | width = 3, | |
88 | relief = 'sunken', | |
89 | bd = 1, | |
90 | fg = self['desiredcolour'], | |
91 | font = value_font) | |
92 | self.desiredlabel.grid(sticky = "nswe", row = 0, column = 2) | |
93 | ||
94 | self.canvas = self.createcomponent('canvas', | |
95 | (), None, | |
96 | Tkinter.Canvas, (interior,), | |
97 | width = 100, | |
98 | height = 300, | |
99 | bg = 'grey') | |
100 | ||
101 | self.canvas.grid(sticky = "nsew", columnspan = 3, pady = 1) | |
102 | self.canvas.bind("<Configure>", self._createGaugeAxes) | |
103 | ||
104 | self._createGaugeAxes() | |
105 | ||
106 | self.initialiseoptions() | |
107 | ||
108 | def _createGaugeAxes(self, event = None): | |
109 | min = self['min'] | |
110 | max = self['max'] | |
111 | units = self['units'] | |
112 | majortickinterval = self['majortickinterval'] | |
113 | ||
114 | gauge_range = max - min | |
115 | ||
116 | c = self.canvas | |
117 | c.delete("all") | |
118 | if event: | |
119 | h, w = event.height, event.width | |
120 | else: | |
121 | h = int(c.configure("height")[4]) | |
122 | w = int(c.configure("width")[4]) | |
123 | ||
124 | self.lower = h - 15 | |
125 | self.upper = 15 | |
126 | self.middle = w / 2 | |
127 | c.create_line(self.middle, self.lower, self.middle, self.upper) | |
128 | ||
129 | majortickcount = int((max - min) / majortickinterval) | |
130 | self.axislength = self.lower - self.upper | |
131 | self.majortickdistance = float(self.axislength) / majortickcount | |
132 | self.majortickwidth = w / 5 | |
133 | labeloffset = (w / 4) + 10 | |
134 | ||
135 | for i in range(majortickcount + 1): | |
136 | v = min + i * majortickinterval | |
137 | d = self.lower - i * self.majortickdistance | |
138 | c.create_line(self.middle, d, self.middle + self.majortickwidth, d) | |
139 | c.create_text(self.middle + labeloffset, d, font = small_font, text = str(v)) | |
140 | ||
141 | self._desiredSet(event) | |
142 | self._actualSet(event) | |
143 | ||
144 | def _backgroundSet(self): | |
145 | self.canvas.configure(bg = self['bg']) | |
146 | ||
147 | def _desiredSet(self, event = None): | |
148 | c = self.canvas | |
149 | desired = self['desiredvalue'] | |
150 | desiredcolour = self['desiredcolour'] | |
151 | ||
152 | min = self['min'] | |
153 | max = self['max'] | |
154 | ||
155 | if desired > max: desired = max | |
156 | if desired < min: desired = min | |
157 | gauge_range = max - min | |
158 | ||
159 | c = self.canvas | |
160 | if event: | |
161 | h, w = event.height, event.width | |
162 | else: | |
163 | h = int(c.configure("height")[4]) | |
164 | w = int(c.configure("width")[4]) | |
165 | ||
166 | ||
167 | desired_y = self.lower - (float(desired - min) / gauge_range) * self.axislength | |
168 | ||
169 | try: | |
170 | c.delete('desiredBar') | |
171 | except: | |
172 | pass | |
173 | ||
174 | c.create_line(self.middle - self.majortickwidth, desired_y, | |
175 | self.middle + self.majortickwidth, desired_y, | |
176 | fill = desiredcolour, stipple = 'gray50', | |
177 | width = 10, tag = 'desiredBar') | |
178 | self.desiredlabel.configure(text = desired) | |
179 | ||
180 | def setActual(self, value): | |
181 | self.configure(actualvalue = value) | |
182 | ||
183 | def getActual(self): | |
184 | return self.cget('actualvalue') | |
185 | ||
186 | def _actualSet(self, event = None): | |
187 | c = self.canvas | |
188 | actual = self['actualvalue'] | |
189 | actualcolour = self['actualcolour'] | |
190 | ||
191 | min = self['min'] | |
192 | max = self['max'] | |
193 | ||
194 | if actual > max: actual = max | |
195 | if actual < min: actual = min | |
196 | gauge_range = max - min | |
197 | ||
198 | c = self.canvas | |
199 | if event: | |
200 | h, w = event.height, event.width | |
201 | else: | |
202 | h = int(c.configure("height")[4]) | |
203 | w = int(c.configure("width")[4]) | |
204 | ||
205 | actual_y = self.lower - (float(actual - min) / gauge_range) * self.axislength | |
206 | ||
207 | try: | |
208 | c.delete('actualPointer') | |
209 | except: | |
210 | pass | |
211 | ||
212 | triangle = ((self.middle, actual_y), | |
213 | (self.middle - 1.4 * self.majortickwidth, actual_y - self.majortickwidth / 2), | |
214 | (self.middle - 1.4 * self.majortickwidth, actual_y + self.majortickwidth / 2)) | |
215 | ||
216 | c.create_polygon(triangle, fill = actualcolour, tag = 'actualPointer') | |
217 | self.actuallabel.configure(text = actual) | |
218 | ||
219 | ||
220 | Pmw.forwardmethods(VerticalGauge, Tkinter.Canvas, 'canvas') | |
221 | ||
222 | if __name__ == '__main__': | |
223 | ||
224 | ||
225 | # Initialise Tkinter and Pmw. | |
226 | root = Pmw.initialise() | |
227 | root.title('Pmw VerticalGauge demonstration') | |
228 | ||
229 | ||
230 | def increase(): | |
231 | av = g1.getActual() | |
232 | g1.setActual(av + 1) | |
233 | ||
234 | def decrease(): | |
235 | av = g1.getActual() | |
236 | g1.setActual(av - 1) | |
237 | ||
238 | g1 = VerticalGauge(min = 0, | |
239 | max = 30, | |
240 | actualvalue = 15, | |
241 | desiredvalue = 22, | |
242 | majortickinterval = 2, | |
243 | label = "Pms") | |
244 | g1.grid(sticky = "nsew") | |
245 | root.grid_rowconfigure(0, weight = 1) | |
246 | root.grid_columnconfigure(0, weight = 1) | |
247 | b1 = Tkinter.Button(text = "Increase", command = increase) | |
248 | b1.grid() | |
249 | b2 = Tkinter.Button(text = "Decrease", command = decrease) | |
250 | b2.grid() | |
251 | ||
252 | # Let's go. | |
253 | root.mainloop() |