1 """GNUmed BMI calculator display widgets.
2
3 acknowledgments: Gui screen Design taken with permission from
4 DrsDesk BMICalc @ DrsDesk Software 1995-2002
5 and @ Dr.R Terry
6 Based on an early screen design by Michael Ireland
7 heavily commented for learning purposes by Dr. R Terry
8
9 copyright: authors
10
11 TODO:
12 - button QUIT
13 - patient related "normal" range
14 - factor out Algo parts
15 """
16
17
18
19 __version__ = "$Revision: 1.13 $"
20 __author__ = "Richard Terry <rterry@gnumed.net>,\
21 Michael Bonert <bonerti@mie.utoronto.ca>,\
22 Karsten Hilbert <Karsten.Hilbert@gmx.net>"
23 __license__ = "GPL v2 or later (details at http://www.gnu.org)"
24
25 import os.path
26
27 import wx
28
29 from Gnumed.pycommon import gmI18N
30
31
33
34 - def __init__(self, parent, color=wx.RED_BRUSH):
35 wx.Window.__init__(self, parent, -1, wx.DefaultPosition,size = (324,25))
36 wx.EVT_PAINT(self, self.OnPaint)
37
39 self.Draw(wx.PaintDC(self))
40
42 dc.BeginDrawing()
43 dc.Clear()
44
45
46
47
48 dc.SetBrush(wx.Brush(wx.Colour(194,194,197), wx.SOLID))
49 dc.SetPen(wx.Pen(wx.Colour(194,197,194), 1))
50 dc.DrawRectangle(0, 0, 324, 30)
51
52
53
54
55
56
57
58
59 dc.SetPen(wx.Pen(wx.Colour(0,0,0), 1))
60 dc.SetBrush(wx.Brush(wx.Colour(255,255,0), wx.SOLID))
61 dc.DrawEllipse(6, 5, 80,15)
62 dc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
63 dc.SetTextForeground(wx.Colour(0,0,0))
64 te = dc.GetTextExtent(_("Underweight"))
65 dc.DrawText(_("Underweight"), 20,9)
66
67
68
69 dc.SetBrush(wx.Brush(wx.Colour(0,194,0), wx.SOLID))
70 dc.DrawEllipse(87, 5, 80,15)
71 dc.SetBrush(wx.Brush(wx.Colour(0,192,0), wx.SOLID))
72 dc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
73 dc.SetTextForeground(wx.Colour(0,0,0))
74 te = dc.GetTextExtent(_("63< Normal >79"))
75 dc.DrawText(_("63 - Normal - 79"),95,8)
76
77
78
79 dc.SetBrush(wx.Brush(wx.Colour(255,128,0), wx.SOLID))
80 dc.DrawEllipse(168, 5, 80,15)
81 dc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
82 dc.SetTextForeground(wx.Colour(0,0,0))
83 te = dc.GetTextExtent(_("Overweight"))
84 dc.DrawText(_("Overweight"), 180,9)
85
86
87
88
89 dc.SetBrush(wx.Brush(wx.Colour(192,0,0), wx.SOLID))
90 dc.DrawEllipse(250, 5, 60,15)
91 dc.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL))
92 dc.SetTextForeground(wx.Colour(0,0,0))
93 te = dc.GetTextExtent(_("Obese"))
94 dc.DrawText(_("Obese"), 267,9)
95 dc.EndDrawing()
96
100
103
104
105 self.low_norm_mass=''
106 self.upp_norm_mass=''
107 self.focus=0
108
109 wx.Panel.__init__ (
110 self,
111 parent = parent,
112 id = id,
113 pos = wx.DefaultPosition,
114 size = wx.DefaultSize,
115 style = wx.SIMPLE_BORDER | wx.TAB_TRAVERSAL
116 )
117
118
119
120 label = wx.StaticText(
121 self,
122 -1,
123 _("Current height/mass"),
124 wx.DefaultPosition,
125 wx.DefaultSize,
126 style = wx.ALIGN_CENTRE
127 )
128 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,''))
129 label.SetForegroundColour(wx.Colour(0,0,131))
130 szr_upper_heading = wx.BoxSizer(wx.HORIZONTAL)
131 szr_upper_heading.Add(label,1,0)
132
133
134
135 label = wx.StaticText(self,-1,_("Height (cm)"),size = (1,20))
136 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
137 label.SetForegroundColour(wx.Colour(0,0,131))
138
139 self.txtheight = wx.TextCtrl(self,-1,"",size=(100,20))
140 self.txtheight.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
141
142 wx.EVT_TEXT(self, self.txtheight.GetId(), self.EvtText_height)
143 wx.EVT_SET_FOCUS(self.txtheight, self.OnSetFocus_height)
144 wx.EVT_CHAR(self.txtheight, self.EvtChar_height)
145
146 szr_height = wx.BoxSizer(wx.HORIZONTAL)
147 szr_height.Add((10,1),0,0)
148 szr_height.Add(label, 1, wx.ALIGN_CENTRE_VERTICAL, 0)
149 szr_height.Add(self.txtheight, 1, wx.ALIGN_CENTRE_VERTICAL | wx.EXPAND, 0)
150
151
152
153 label = wx.StaticText(self,-1,_("Mass (kg)"),size = (20,20))
154 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
155 label.SetForegroundColour(wx.Colour(0,0,131))
156
157 self.txtmass = wx.TextCtrl(self,-1,"",size=(100,20))
158 self.txtmass.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
159
160 wx.EVT_TEXT(self, self.txtmass.GetId(), self.EvtText_mass)
161 wx.EVT_SET_FOCUS(self.txtmass, self.OnSetFocus_mass)
162 wx.EVT_CHAR(self.txtmass, self.EvtChar_mass)
163
164 szr_mass = wx.BoxSizer(wx.HORIZONTAL)
165 szr_mass.Add((10,1),0,0)
166 szr_mass.Add(label, 1, wx.ALIGN_CENTRE_VERTICAL, 0)
167 szr_mass.Add(self.txtmass, 1, wx.ALIGN_CENTRE_VERTICAL | wx.EXPAND, 0)
168 szr_mass.Add((5,5),1,0)
169
170
171
172 label = wx.StaticText(self,-1,_("BMI"),size = (100,20))
173 label.SetFont(wx.Font(13,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
174 label.SetForegroundColour(wx.Colour(0,0,131))
175
176 self.txtbmi = wx.TextCtrl(self,-1,"",size=(100,20), style = wx.TE_READONLY)
177 self.txtbmi.Enable(False)
178 self.txtbmi.SetFont(wx.Font(13,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
179
180 szr_bmi = wx.BoxSizer(wx.HORIZONTAL)
181 szr_bmi.Add((10,1),0,0)
182 szr_bmi.Add(label,1,wx.ALIGN_CENTRE_VERTICAL|0,0)
183 szr_bmi.Add(self.txtbmi,1,wx.ALIGN_CENTRE_VERTICAL | wx.EXPAND,0)
184 szr_bmi.Add((5,5),1,0)
185
186
187
188 bmi_colour_scale = BMI_Colour_Scale(self)
189 bmi_colour_scale.Enable(False)
190 szr_col_scale = wx.BoxSizer(wx.HORIZONTAL)
191 szr_col_scale.Add(bmi_colour_scale,1,wx.EXPAND)
192
193
194
195 self.slider = wx.Slider(self, -1, 15, 15, 34, wx.Point(30, 60),
196 wx.Size(324, -1),
197 wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS )
198 self.slider.SetTickFreq(1, 1)
199 wx.EVT_SCROLL(self.slider, self.SLIDER_EVT)
200 wx.EVT_CHAR(self.slider, self.EvtChar_slider)
201
202 szr_slider = wx.BoxSizer(wx.HORIZONTAL)
203 szr_slider.Add(self.slider,1,wx.EXPAND)
204
205
206
207
208 label = wx.StaticText(
209 self,
210 -1,
211 _("Adjusted Values"),
212 wx.DefaultPosition,
213 wx.DefaultSize,
214 style = wx.ALIGN_CENTRE
215 )
216 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,''))
217 label.SetForegroundColour(wx.Colour(0,0,131))
218
219 szr_lower_heading = wx.BoxSizer(wx.HORIZONTAL)
220 szr_lower_heading.Add(label,1,wx.EXPAND)
221
222
223
224 label = wx.StaticText(self,-1,_("Goal mass"),size = (30,20))
225 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
226 label.SetForegroundColour(wx.Colour(0,0,131))
227
228 self.txtgoal= wx.TextCtrl(self,-1,"",size=(100,20))
229 self.txtgoal.SetFont(wx.Font(14,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
230
231 wx.EVT_TEXT(self, self.txtgoal.GetId(), self.EvtText_goal)
232 wx.EVT_SET_FOCUS(self.txtgoal, self.OnSetFocus_goal)
233 wx.EVT_CHAR(self.txtgoal, self.EvtChar_goal)
234
235 szr_goal_mass = wx.BoxSizer(wx.HORIZONTAL)
236 szr_goal_mass.Add((10,1),0,0)
237 szr_goal_mass.Add(label,1,wx.ALIGN_CENTRE_VERTICAL,0)
238 szr_goal_mass.Add(self.txtgoal,1,wx.ALIGN_CENTRE_VERTICAL | wx.EXPAND, 0)
239
240
241
242 label = wx.StaticText(self,-1,_("kg to lose"),size = (30,20))
243 label.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
244 label.SetForegroundColour(wx.Colour(0,0,131))
245
246 self.txtloss= wx.TextCtrl(self,-1,"",size=(100,20))
247 self.txtloss.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL,wx.NORMAL,False,''))
248
249 wx.EVT_TEXT(self, self.txtloss.GetId(), self.EvtText_loss)
250 wx.EVT_SET_FOCUS(self.txtloss, self.OnSetFocus_loss)
251 wx.EVT_CHAR(self.txtloss, self.EvtChar_loss)
252
253 szr_to_loose = wx.BoxSizer(wx.HORIZONTAL)
254 szr_to_loose.Add((10,1),0,0)
255 szr_to_loose.Add(label,1,wx.ALIGN_CENTRE_VERTICAL,0)
256 szr_to_loose.Add(self.txtloss,1,wx.ALIGN_CENTRE_VERTICAL | wx.EXPAND,0)
257
258
259
260 szr_main = wx.BoxSizer(wx.VERTICAL)
261 szr_main.Add((1,5),0,0)
262 szr_main.Add(szr_upper_heading,0,wx.EXPAND)
263 szr_main.Add((1,5),0,0)
264 szr_main.Add(szr_height,0,0)
265 szr_main.Add((1,5),0,0)
266 szr_main.Add(szr_mass,0,0)
267 szr_main.Add((1,5),0,0)
268 szr_main.Add(szr_bmi,0,0)
269 szr_main.Add((1,20),0,0)
270 szr_main.Add(szr_col_scale,0,0)
271 szr_main.Add(szr_slider,0,0)
272 szr_main.Add(szr_lower_heading,0,wx.EXPAND)
273 szr_main.Add((1,5),0,0)
274 szr_main.Add(szr_goal_mass,0,0)
275 szr_main.Add((1,5),0,0)
276 szr_main.Add(szr_to_loose,0,0)
277 szr_main.Add((1,20),0,0)
278
279
280
281 self.SetSizer(szr_main)
282 szr_main.Fit(self)
283 self.SetAutoLayout(True)
284 self.Show(True)
285
286
287
291
295
299
303
304 - def EvtText_height(self, event):
305 if(self.focus==1):
306 self.calc_ideal_mass_range()
307 self.CalcBMI()
308
309 - def EvtText_mass(self, event):
310 if(self.focus==2):
311 self.CalcBMI()
312
313 - def EvtText_goal(self, event):
314 if(self.focus==4):
315 if(self.txtgoal.GetValue()!=''):
316 try:
317 self.txtloss.SetValue(str(eval(self.txtmass.GetValue())-eval(self.txtgoal.GetValue())))
318 self.CalcNEWBMI()
319 except Exception:
320 pass
321 else:
322 self.txtloss.SetValue('')
323
324 - def EvtText_loss(self, event):
325 if(self.focus==5):
326 self.loss=event.GetString()
327
328 if(self.txtloss.GetValue()!=''):
329 try:
330 self.txtgoal.SetValue(str(eval(self.txtmass.GetValue())-eval(self.txtloss.GetValue())))
331 self.CalcNEWBMI()
332 except Exception:
333 pass
334 else:
335 self.txtgoal.SetValue('')
336
338
339 try:
340 self.low_norm_mass=20.*((eval(self.txtheight.GetValue())/100.)**2)
341 self.upp_norm_mass=25.*((eval(self.txtheight.GetValue())/100.)**2)
342
343
344
345 except Exception:
346 pass
347
349 if(self.txtheight.GetValue()=='' or self.txtmass.GetValue()==''):
350 self.txtbmi.SetValue('')
351 else:
352 try:
353 self.txtbmi.SetValue(str(round(eval(self.txtmass.GetValue())/((eval(self.txtheight.GetValue())/100.)**2),1)))
354
355
356
357 self.NEWBMI=round(round(eval(self.txtmass.GetValue())/((eval(self.txtheight.GetValue())/100.)**2),1),0)
358 self.slider.SetValue(int (self.NEWBMI))
359
360
361
362
363
364
365
366
367
368 except Exception:
369 pass
370
372 self.NEWBMI=round(eval(self.txtgoal.GetValue())/((eval(self.txtheight.GetValue())/100.)**2),0)
373 self.slider.SetValue(int (self.NEWBMI))
374
376 self.NEWBMI=self.slider.GetValue()
377 try:
378 self.txtgoal.SetValue(str(round(self.NEWBMI*(eval(self.txtheight.GetValue())/100.)**2,1)))
379 self.txtloss.SetValue(str(eval(self.txtmass.GetValue())-eval(self.txtgoal.GetValue())))
380 except Exception:
381 pass
382
383
389
395
401
407
413
414
415
416
417
418
420
422
423
424 wx.Frame.__init__(
425 self,
426 parent,
427 -1,
428 _("BMI Calculator"),
429 style = wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.CAPTION | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL | wx.TAB_TRAVERSAL | wx.STAY_ON_TOP
430 )
431 wx.EVT_CLOSE(self, self.OnCloseWindow)
432
433
434
435
436 self.pnl_bmi = BMICalc_Panel(self,-1)
437
438
439
440
441
442
443
444
445
446
447
448 text4graph = wx.TextCtrl(
449 self,
450 -1,
451 "Hi Guys, this is a prototype BMI Calculator + graph.\n\n"
452 "Comments please to rterry@gnumed.net..\n\n"
453 "Can someone tell me how to centre this frame on the screen...\n\n"
454 "This text box needs to be replaced by a graph class....\n"
455 "which amongst other things could show this patients mass trends!!!!\n\n"
456 "The mass range on the green epilpse would be calculated for each patient...\n\n"
457 "BTW, don't worry about your weight, the 'normal' range (63-79) is hardcoded.",
458 size=(200, 100),
459 style = wx.TE_MULTILINE | wx.TE_READONLY
460 )
461
462
463 gszr_right_buttons = wx.GridSizer(1, 4, 1, 4)
464 gszr_right_buttons.AddMany([
465 (wx.Button(self, 1010, _('&Reset')), 0, wx.EXPAND)
466
467
468
469
470 ])
471
472 wx.EVT_BUTTON(self,1010,self.EvtReset)
473
474
475
476
477
478 szr_right_col = wx.BoxSizer(wx.VERTICAL)
479 szr_right_col.Add(text4graph,1,wx.EXPAND)
480 szr_right_col.Add((1,5),0,wx.EXPAND)
481 szr_right_col.Add(gszr_right_buttons,0,wx.EXPAND)
482
483
484
485
486
487
488
489
490 szr_main = wx.BoxSizer(wx.HORIZONTAL)
491 szr_main.Add(self.pnl_bmi, 0, wx.EXPAND | wx.ALL, 10)
492 szr_main.Add((5, 0), 0, wx.EXPAND)
493 szr_main.Add(szr_right_col, 1, wx.EXPAND | wx.ALL, 10)
494
495 self.SetSizer(szr_main)
496 szr_main.Fit(self)
497 self.SetAutoLayout(True)
498
499
500 if __name__ == '__main__':
501 png_fname = os.path.join('..', 'bitmaps', 'bmi_calculator.png')
502 else:
503 from Gnumed.pycommon import gmGuiBroker
504 gb = gmGuiBroker.GuiBroker()
505 png_fname = os.path.join(gb['gnumed_dir'], 'bitmaps', 'bmi_calculator.png')
506 icon = wx.Icon()
507 icon.LoadFile(png_fname, wx.BITMAP_TYPE_PNG)
508 self.SetIcon(icon)
509
511
512 self.pnl_bmi.low_norm_mass=''
513 self.pnl_bmi.upp_norm_mass=''
514
515
516 self.pnl_bmi.txtheight.SetValue('')
517 self.pnl_bmi.txtmass.SetValue('')
518 self.pnl_bmi.txtbmi.SetValue('')
519 self.pnl_bmi.txtgoal.SetValue('')
520 self.pnl_bmi.txtloss.SetValue('')
521 self.pnl_bmi.slider.SetValue(0)
522
523
526
529
532
535
536
537 if __name__ == '__main__':
538
541 frame = BMI_Frame(None)
542 frame.Show(True)
543 return True
544
545 wx.InitAllImageHandlers()
546 app = TestApp()
547 app.MainLoop()
548
549
550