Package Gnumed :: Package wxpython :: Module gmAllergyWidgets
[frames] | no frames]

Source Code for Module Gnumed.wxpython.gmAllergyWidgets

  1  """GNUmed allergy related widgets.""" 
  2  ############################################################################ 
  3  __version__ = "$Revision: 1.36 $" 
  4  __author__  = "R.Terry <rterry@gnumed.net>, H.Herb <hherb@gnumed.net>, K.Hilbert <Karsten.Hilbert@gmx.net>" 
  5  __license__ = 'GPL v2 or later (details at http://www.gnu.org)' 
  6   
  7  import sys, time, datetime as pyDT, logging 
  8   
  9   
 10  import wx 
 11   
 12   
 13  if __name__ == '__main__': 
 14          sys.path.insert(0, '../../') 
 15  from Gnumed.pycommon import gmDispatcher, gmI18N, gmDateTime, gmTools, gmMatchProvider 
 16  from Gnumed.wxpython import gmDateTimeInput, gmTerryGuiParts, gmRegetMixin, gmPatSearchWidgets 
 17  from Gnumed.business import gmPerson, gmAllergy, gmPersonSearch 
 18  from Gnumed.wxGladeWidgets import wxgAllergyEditAreaPnl, wxgAllergyEditAreaDlg, wxgAllergyManagerDlg 
 19   
 20  _log = logging.getLogger('gm.ui') 
 21  _log.info(__version__) 
 22   
 23  #====================================================================== 
24 -class cAllergyEditAreaPnl(wxgAllergyEditAreaPnl.wxgAllergyEditAreaPnl):
25
26 - def __init__(self, *args, **kwargs):
27 wxgAllergyEditAreaPnl.wxgAllergyEditAreaPnl.__init__(self, *args, **kwargs) 28 29 try: 30 self.__allergy = kwargs['allergy'] 31 except KeyError: 32 self.__allergy = None 33 34 mp = gmMatchProvider.cMatchProvider_SQL2 ( 35 queries = [u""" 36 select substance, substance 37 from clin.allergy 38 where substance %(fragment_condition)s 39 40 union 41 42 select generics, generics 43 from clin.allergy 44 where generics %(fragment_condition)s 45 46 union 47 48 select allergene, allergene 49 from clin.allergy 50 where allergene %(fragment_condition)s 51 52 union 53 54 select atc_code, atc_code 55 from clin.allergy 56 where atc_code %(fragment_condition)s 57 """ 58 ] 59 ) 60 mp.setThresholds(2, 3, 5) 61 self._PRW_trigger.matcher = mp 62 63 mp = gmMatchProvider.cMatchProvider_SQL2 ( 64 queries = [u""" 65 select narrative, narrative 66 from clin.allergy 67 where narrative %(fragment_condition)s 68 """] 69 ) 70 mp.setThresholds(2, 3, 5) 71 self._PRW_reaction.matcher = mp 72 self._PRW_reaction.enable_default_spellchecker() 73 74 # self._RBTN_type_sensitivity.MoveAfterInTabOrder(self._RBTN_type_allergy) 75 # self._ChBOX_definite.MoveAfterInTabOrder(self._RBTN_type_sensitivity) 76 77 self.refresh()
78 #-------------------------------------------------------- 79 # external API 80 #--------------------------------------------------------
81 - def clear(self):
82 self.__allergy = None 83 return self.refresh()
84 #--------------------------------------------------------
85 - def refresh(self, allergy=None):
86 87 if allergy is not None: 88 self.__allergy = allergy 89 90 if self.__allergy is None: 91 ts = gmDateTime.cFuzzyTimestamp ( 92 timestamp = pyDT.datetime.now(tz=gmDateTime.gmCurrentLocalTimezone), 93 accuracy = gmDateTime.acc_days 94 ) 95 self._DPRW_date_noted.SetData(data = ts) 96 self._PRW_trigger.SetText() 97 self._TCTRL_brand_name.SetValue('') 98 self._TCTRL_generic.SetValue('') 99 self._ChBOX_generic_specific.SetValue(0) 100 self._TCTRL_atc_classes.SetValue('') 101 self._PRW_reaction.SetText() 102 self._RBTN_type_allergy.SetValue(1) 103 self._RBTN_type_sensitivity.SetValue(0) 104 self._ChBOX_definite.SetValue(1) 105 return True 106 107 if not isinstance(self.__allergy, gmAllergy.cAllergy): 108 raise ValueError('[%s].refresh(): expected gmAllergy.cAllergy instance, got [%s] instead' % (self.__class__.__name__, self.__allergy)) 109 110 ts = gmDateTime.cFuzzyTimestamp ( 111 timestamp = self.__allergy['date'], 112 accuracy = gmDateTime.acc_days 113 ) 114 self._DPRW_date_noted.SetData(data=ts) 115 self._PRW_trigger.SetText(value = self.__allergy['allergene']) 116 self._TCTRL_brand_name.SetValue(self.__allergy['substance']) 117 self._TCTRL_generic.SetValue(gmTools.coalesce(self.__allergy['generics'], '')) 118 self._ChBOX_generic_specific.SetValue(self.__allergy['generic_specific']) 119 self._TCTRL_atc_classes.SetValue(gmTools.coalesce(self.__allergy['atc_code'], '')) 120 self._PRW_reaction.SetText(value = gmTools.coalesce(self.__allergy['reaction'], '')) 121 if self.__allergy['type'] == 'allergy': 122 self._RBTN_type_allergy.SetValue(1) 123 else: 124 self._RBTN_type_sensitivity.SetValue(1) 125 self._ChBOX_definite.SetValue(self.__allergy['definite'])
126 #--------------------------------------------------------
127 - def __is_valid_for_save(self):
128 129 if self._PRW_trigger.GetValue().strip() == '': 130 self._PRW_trigger.SetBackgroundColour('pink') 131 self._PRW_trigger.Refresh() 132 self._PRW_trigger.SetFocus() 133 return False 134 self._PRW_trigger.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)) 135 self._PRW_trigger.Refresh() 136 137 return True
138 #--------------------------------------------------------
139 - def save(self, can_create=True):
140 if not self.__is_valid_for_save(): 141 return False 142 143 if self.__allergy is None: 144 if not can_create: 145 gmDispatcher.send(signal='statustext', msg=_('Creating new allergy not allowed.')) 146 return False 147 148 pat = gmPerson.gmCurrentPatient() 149 emr = pat.get_emr() 150 151 if self._RBTN_type_allergy.GetValue(): 152 allg_type = 'allergy' 153 else: 154 allg_type = 'sensitivity' 155 self.__allergy = emr.add_allergy ( 156 allergene = self._PRW_trigger.GetValue().strip(), 157 allg_type = allg_type 158 ) 159 160 # and update it with known data 161 self.__allergy['date'] = self._DPRW_date_noted.GetData().get_pydt() 162 self.__allergy['allergene'] = self._PRW_trigger.GetValue().strip() 163 # FIXME: determine brandname/generic/etc from substance (trigger field) 164 self.__allergy['generic_specific'] = (True and self._ChBOX_generic_specific.GetValue()) 165 self.__allergy['reaction'] = self._PRW_reaction.GetValue().strip() 166 self.__allergy['definite'] = (True and self._ChBOX_definite.GetValue()) 167 if self._RBTN_type_allergy.GetValue(): 168 self.__allergy['pk_type'] = 'allergy' 169 else: 170 self.__allergy['pk_type'] = 'sensitivity' 171 172 self.__allergy.save_payload() 173 174 return True
175 #======================================================================
176 -class cAllergyEditAreaDlg(wxgAllergyEditAreaDlg.wxgAllergyEditAreaDlg):
177
178 - def __init__(self, *args, **kwargs):
179 180 try: 181 allergy = kwargs['allergy'] 182 del kwargs['allergy'] 183 except KeyError: 184 allergy = None 185 186 wxgAllergyEditAreaDlg.wxgAllergyEditAreaDlg.__init__(self, *args, **kwargs) 187 188 if allergy is None: 189 # self._BTN_save.SetLabel(_('&Save')) 190 self._BTN_clear.SetLabel(_('&Clear')) 191 else: 192 # self._BTN_save.SetLabel(_('Update')) 193 self._BTN_clear.SetLabel(_('&Restore')) 194 195 self._PNL_edit_area.refresh(allergy = allergy)
196 #--------------------------------------------------------
197 - def _on_save_button_pressed(self, evt):
198 if self._PNL_edit_area.save(): 199 if self.IsModal(): 200 self.EndModal(wx.ID_OK) 201 else: 202 self.Close()
203 #--------------------------------------------------------
204 - def _on_clear_button_pressed(self, evt):
205 self._PNL_edit_area.refresh()
206 #======================================================================
207 -class cAllergyManagerDlg(wxgAllergyManagerDlg.wxgAllergyManagerDlg):
208
209 - def __init__(self, *args, **kwargs):
210 211 wxgAllergyManagerDlg.wxgAllergyManagerDlg.__init__(self, *args, **kwargs) 212 213 self.Centre(direction = wx.BOTH) 214 215 self.__set_columns() 216 # MacOSX crashes on this with: 217 # exception type : wx._core.PyAssertionError 218 # exception value: C++ assertion "i" failed at /BUILD/wxPython-src-2.8.3.0/src/common/wincmn.cpp(2634) in DoMoveInTabOrder(): MoveBefore/AfterInTabOrder(): win is not a sibling 219 # while Win/Linux work just fine 220 #self._PNL_edit_area._ChBOX_definite.MoveAfterInTabOrder(self._BTN_save) 221 self.__refresh_state_ui() 222 self.__refresh_details_ui()
223 #-------------------------------------------------------- 224 # internal helpers 225 #--------------------------------------------------------
226 - def __set_columns(self):
227 self._LCTRL_allergies.set_columns (columns = [ 228 _('Type'), 229 _('Certainty'), 230 _('Trigger'), 231 _('Reaction') 232 ])
233 #--------------------------------------------------------
234 - def __refresh_state_ui(self):
235 236 pat = gmPerson.gmCurrentPatient() 237 emr = pat.get_emr() 238 state = emr.allergy_state 239 240 self._TXT_current_state.SetLabel(state.state_string) 241 242 if state['last_confirmed'] is None: 243 self._TXT_last_confirmed.SetLabel(_('<allergy state unasked>')) 244 else: 245 self._TXT_last_confirmed.SetLabel(state['last_confirmed'].strftime('%x %H:%M')) 246 247 if state['has_allergy'] is None: 248 self._RBTN_unknown.SetValue(True) 249 self._RBTN_none.SetValue(False) 250 self._RBTN_some.SetValue(False) 251 252 self._RBTN_unknown.Enable(True) 253 self._RBTN_none.Enable(True) 254 255 elif state['has_allergy'] == 0: 256 self._RBTN_unknown.SetValue(False) 257 self._RBTN_none.SetValue(True) 258 self._RBTN_some.SetValue(False) 259 260 self._RBTN_unknown.Enable(True) 261 self._RBTN_none.Enable(True) 262 263 elif state['has_allergy'] == 1: 264 self._RBTN_unknown.SetValue(False) 265 self._RBTN_none.SetValue(False) 266 self._RBTN_some.SetValue(True) 267 268 self._RBTN_unknown.Enable(True) 269 self._RBTN_none.Enable(False) 270 271 else: 272 self._RBTN_unknown.SetValue(True) 273 self._RBTN_none.SetValue(False) 274 self._RBTN_some.SetValue(False) 275 276 self._RBTN_unknown.Enable(True) 277 self._RBTN_none.Enable(True) 278 279 gmDispatcher.send(signal=u'statustext', msg=_('invalid allergy state [%s]') % state, beep=True) 280 281 if state['comment'] is not None: 282 self._TCTRL_state_comment.SetValue(state['comment'])
283 #--------------------------------------------------------
284 - def __refresh_details_ui(self):
285 286 pat = gmPerson.gmCurrentPatient() 287 emr = pat.get_emr() 288 allergies = emr.get_allergies() 289 no_of_allergies = len(allergies) 290 291 # display allergies 292 self._LCTRL_allergies.DeleteAllItems() 293 if no_of_allergies > 0: 294 emr.allergy_state = 1 295 296 for allergy in allergies: 297 row_idx = self._LCTRL_allergies.InsertStringItem(no_of_allergies, label = allergy['l10n_type']) 298 if allergy['definite']: 299 label = _('definite') 300 else: 301 label = u'' 302 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 1, label = label) 303 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 2, label = allergy['descriptor']) 304 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 3, label = gmTools.coalesce(allergy['reaction'], u'')) 305 self._LCTRL_allergies.set_data(data=allergies) 306 307 self._LCTRL_allergies.Enable(True) 308 self._RBTN_some.SetValue(True) 309 self._RBTN_unknown.Enable(False) 310 self._RBTN_none.Enable(False) 311 else: 312 self._LCTRL_allergies.Enable(False) 313 self._RBTN_unknown.Enable(True) 314 self._RBTN_none.Enable(True) 315 316 self._LCTRL_allergies.set_column_widths (widths = [ 317 wx.LIST_AUTOSIZE, 318 wx.LIST_AUTOSIZE, 319 wx.LIST_AUTOSIZE, 320 wx.LIST_AUTOSIZE 321 ]) 322 323 self._PNL_edit_area.clear() 324 self._BTN_delete.Enable(False)
325 #-------------------------------------------------------- 326 # event handlers 327 #--------------------------------------------------------
328 - def _on_dismiss_button_pressed(self, evt):
329 if self.IsModal(): 330 self.EndModal(wx.ID_OK) 331 else: 332 self.Close()
333 #--------------------------------------------------------
334 - def _on_clear_button_pressed(self, evt):
335 self._LCTRL_allergies.deselect_selected_item() 336 self._PNL_edit_area.clear() 337 self._BTN_delete.Enable(False) 338 self._LBL_message.SetLabel(_('Input new allergy item:'))
339 #--------------------------------------------------------
340 - def _on_delete_button_pressed(self, evt):
341 pat = gmPerson.gmCurrentPatient() 342 emr = pat.get_emr() 343 344 allergy = self._LCTRL_allergies.get_selected_item_data(only_one=True) 345 if allergy is None: 346 return 347 emr.delete_allergy(pk_allergy = allergy['pk_allergy']) 348 349 state = emr.allergy_state 350 state['last_confirmed'] = u'now' 351 state.save_payload() 352 353 self.__refresh_state_ui() 354 self.__refresh_details_ui()
355 #--------------------------------------------------------
356 - def _on_list_item_selected(self, evt):
357 allergy = self._LCTRL_allergies.get_selected_item_data(only_one=True) 358 if allergy is None: 359 return 360 self._PNL_edit_area.refresh(allergy = allergy) 361 self._BTN_delete.Enable(True) 362 self._LBL_message.SetLabel(_('Edit the selected allergy item:'))
363 #--------------------------------------------------------
364 - def _on_confirm_button_pressed(self, evt):
365 pat = gmPerson.gmCurrentPatient() 366 emr = pat.get_emr() 367 allergies = emr.get_allergies() 368 state = emr.allergy_state 369 370 cmt = self._TCTRL_state_comment.GetValue().strip() 371 372 if self._RBTN_unknown.GetValue(): 373 if len(allergies) > 0: 374 gmDispatcher.send(signal = u'statustext', msg = _('Cannot set allergy state to <unknown> because there are allergies stored for this patient.'), beep = True) 375 self._RBTN_some.SetValue(True) 376 state['has_allergy'] = 1 377 return False 378 else: 379 state['has_allergy'] = None 380 381 elif self._RBTN_none.GetValue(): 382 if len(allergies) > 0: 383 gmDispatcher.send(signal = u'statustext', msg = _('Cannot set allergy state to <None> because there are allergies stored for this patient.'), beep = True) 384 self._RBTN_some.SetValue(True) 385 state['has_allergy'] = 1 386 return False 387 else: 388 state['has_allergy'] = 0 389 390 elif self._RBTN_some.GetValue(): 391 if (len(allergies) == 0) and (cmt == u''): 392 gmDispatcher.send(signal = u'statustext', msg = _('Cannot set allergy state to <some> because there are neither allergies nor a comment available for this patient.'), beep = True) 393 return False 394 else: 395 state['has_allergy'] = 1 396 397 state['comment'] = cmt 398 state['last_confirmed'] = u'now' 399 400 state.save_payload() 401 self.__refresh_state_ui()
402 #--------------------------------------------------------
403 - def _on_save_details_button_pressed(self, evt):
404 405 if not self._PNL_edit_area.save(): 406 return False 407 408 pat = gmPerson.gmCurrentPatient() 409 emr = pat.get_emr() 410 state = emr.allergy_state 411 state['last_confirmed'] = u'now' 412 state.save_payload() 413 414 self.__refresh_state_ui() 415 self.__refresh_details_ui()
416 #======================================================================
417 -class cAllergyPanel(wx.Panel, gmRegetMixin.cRegetOnPaintMixin):
418 """Allergy details panel. 419 420 This panel will hold all the allergy details and 421 allow entry of those details via the editing area. 422 """ 423 #----------------------------------------------------
424 - def __init__(self, parent, id=-1):
425 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.RAISED_BORDER) 426 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 427 self.__do_layout() 428 self.__pat = gmPerson.gmCurrentPatient() 429 self.__register_interests() 430 self.__reset_ui_content()
431 #----------------------------------------------------
432 - def __do_layout(self):
433 # -- top part -- 434 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _("ALLERGIES")) 435 self.editarea = gmAllergyEditArea(self, -1) 436 437 # -- middle part -- 438 # divider headings below edit area 439 pnl_MiddleCaption = gmTerryGuiParts.cDividerCaption(self, -1, _("Allergy and Sensitivity - Summary")) 440 # self.sizer_divider_drug_generic = wx.BoxSizer(wxHORIZONTAL) 441 # self.sizer_divider_drug_generic.Add(pnl_MiddleCaption, 1, wxEXPAND) 442 self.LCTRL_allergies = wx.ListCtrl ( 443 parent = self, 444 id = ID_ALLERGY_LIST, 445 pos = wx.DefaultPosition, 446 size = wx.DefaultSize, 447 style = wx.LC_SINGLE_SEL | wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES | wx.LC_VRULES | wx.VSCROLL 448 ) 449 self.LCTRL_allergies.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 450 self.LCTRL_allergies.InsertColumn(0, _("Type")) 451 self.LCTRL_allergies.InsertColumn(1, _("Status")) 452 self.LCTRL_allergies.InsertColumn(2, _("ATC/Class")) 453 self.LCTRL_allergies.InsertColumn(3, _("Substance")) 454 self.LCTRL_allergies.InsertColumn(4, _("Generics")) 455 self.LCTRL_allergies.InsertColumn(5, _("Reaction")) 456 457 # -- bottom part -- 458 pnl_LowerCaption = gmTerryGuiParts.cDividerCaption(self, -1, _('Class notes')) 459 #add a richtext control or a wxTextCtrl multiline to display the class text information 460 #e.g. would contain say information re the penicillins 461 self.class_notes = wx.TextCtrl ( 462 self, 463 -1, 464 "A member of a new class of nonsteroidal anti-inflammatory agents (COX-2 selective NSAIDs) which have a mechanism of action that inhibits prostaglandin synthesis primarily by inhibition of cyclooxygenase 2 (COX-2). At therapeutic doses these have no effect on prostanoids synthesised by activation of COX-1 thereby not interfering with normal COX-1 related physiological processes in tissues, particularly the stomach, intestine and platelets.", 465 size = (200, 100), 466 style = wx.TE_MULTILINE | wx.TE_READONLY 467 ) 468 self.class_notes.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 469 470 # -- add elements to main background sizer -- 471 self.mainsizer = wx.BoxSizer(wx.VERTICAL) 472 self.mainsizer.Add(pnl_UpperCaption, 0, wx.EXPAND) 473 self.mainsizer.Add(self.editarea, 6, wx.EXPAND) 474 # self.mainsizer.Add(self.sizer_divider_drug_generic,0,wxEXPAND) 475 self.mainsizer.Add(pnl_MiddleCaption, 0, wx.EXPAND) 476 self.mainsizer.Add(self.LCTRL_allergies, 5, wx.EXPAND) 477 self.mainsizer.Add(pnl_LowerCaption, 0, wx.EXPAND) 478 self.mainsizer.Add(self.class_notes, 4, wx.EXPAND) 479 480 self.SetAutoLayout(True) 481 self.SetSizer(self.mainsizer) 482 self.mainsizer.Fit(self)
483 #-----------------------------------------------
484 - def __register_interests(self):
485 wx.EVT_LIST_ITEM_ACTIVATED(self, ID_ALLERGY_LIST, self._on_allergy_activated) 486 487 # client internal signals 488 gmDispatcher.connect(signal = u'post_patient_selection', receiver=self._schedule_data_reget)
489 # gmDispatcher.connect(signal = u'vaccinations_updated', receiver=self._schedule_data_reget) 490 #-----------------------------------------------
491 - def __reset_ui_content(self):
492 self.editarea.set_data() 493 self.LCTRL_allergies.DeleteAllItems()
494 #-----------------------------------------------
495 - def _populate_with_data(self):
496 if not self.__pat.connected: 497 return False 498 499 self.LCTRL_allergies.DeleteAllItems() 500 501 emr = self.__pat.get_emr() 502 allergies = emr.get_allergies() 503 if allergies is None: 504 return False 505 for list_line in range(len(allergies)): 506 allg = allergies[list_line] 507 list_line = self.LCTRL_allergies.InsertStringItem(list_line, allg['l10n_type']) 508 # FIXME: check with Richard design specs 509 if allg['definite']: 510 self.LCTRL_allergies.SetStringItem(list_line, 1, _('definite')) 511 else: 512 self.LCTRL_allergies.SetStringItem(list_line, 1, _('likely')) 513 if allg['atc_code'] is not None: 514 self.LCTRL_allergies.SetStringItem(list_line, 2, allg['atc_code']) 515 self.LCTRL_allergies.SetStringItem(list_line, 3, allg['substance']) 516 if allg['generics'] is not None: 517 self.LCTRL_allergies.SetStringItem(list_line, 4, allg['generics']) 518 self.LCTRL_allergies.SetStringItem(list_line, 5, allg['reaction']) 519 self.LCTRL_allergies.SetItemData(list_line, allg['pk_allergy']) 520 for col in range(5): 521 self.LCTRL_allergies.SetColumnWidth(col, wx.LIST_AUTOSIZE) 522 # FIXME: resize event needed ? 523 return True
524 #-----------------------------------------------
525 - def _on_allergy_activated(self, evt):
526 pk_allg = evt.GetData() 527 emr = self.__pat.get_emr() 528 allgs = emr.get_allergies(ID_list=[pk_allg]) 529 self.editarea.set_data(allergy = allgs[0])
530 #====================================================================== 531 # main 532 #---------------------------------------------------------------------- 533 if __name__ == "__main__": 534 535 gmI18N.activate_locale() 536 gmI18N.install_domain(domain='gnumed') 537 538 #-----------------------------------------------
539 - def test_allergy_edit_area_dlg():
540 app = wx.PyWidgetTester(size = (600, 600)) 541 dlg = cAllergyEditAreaDlg(parent=app.frame, id=-1) 542 dlg.ShowModal() 543 # emr = pat.get_emr() 544 # allergy = emr.get_allergies()[0] 545 # dlg = cAllergyEditAreaDlg(parent=app.frame, id=-1, allergy=allergy) 546 # dlg.ShowModal() 547 return
548 #-----------------------------------------------
549 - def test_allergy_manager_dlg():
550 app = wx.PyWidgetTester(size = (800, 600)) 551 dlg = cAllergyManagerDlg(parent=app.frame, id=-1) 552 dlg.ShowModal() 553 return
554 #----------------------------------------------- 555 if len(sys.argv) > 1 and sys.argv[1] == 'test': 556 557 pat = gmPersonSearch.ask_for_patient() 558 if pat is None: 559 sys.exit(0) 560 gmPatSearchWidgets.set_active_patient(pat) 561 562 #test_allergy_edit_area_dlg() 563 test_allergy_manager_dlg() 564 565 # app = wxPyWidgetTester(size = (600, 600)) 566 # app.SetWidget(cAllergyPanel, -1) 567 # app.MainLoop() 568 #====================================================================== 569