def Init(self, structures, dose, plan, dvhs): """Method called after the panel has been initialized.""" # Initialize the Conformality selector controls self.lblType = XRCCTRL(self, 'lblType') self.choiceConformalityStructure = XRCCTRL( self, 'choiceConformalityStructure') self.choiceConformalityDose = XRCCTRL(self, 'choiceConformalityDose') self.lblConformalityIndex = XRCCTRL(self, 'lblConformalityIndex') self.lblUnderdoseRatio = XRCCTRL(self, 'lblUnderdoseRatio') self.lblOverdoseRatio = XRCCTRL(self, 'lblOverdoseRatio') self.lblTargetVolume = XRCCTRL(self, 'lblTargetVolume') self.lblCoverageVolume = XRCCTRL(self, 'lblCoverageVolume') self.lblIsodoseVolume = XRCCTRL(self, 'lblIsodoseVolume') # Bind ui events to the proper methods wx.EVT_CHOICE(self, XRCID('choiceConformalityStructure'), self.OnStructureSelect) wx.EVT_CHOICE(self, XRCID('choiceConformalityDose'), self.OnIsodoseSelect) # Initialize variables self.structures = structures self.dose = dose self.rxdose = plan['rxdose'] self.dvhs = dvhs self.conformalitydata = {} self.structureid = {} self.dvhdata = {} self.PopulateStructureChoices()
def LoadPlugins(self): """Update and load the data for the plugin list control.""" # Set up the plugins for each plugin entry point of dicompyler for n, plugin in enumerate(self.plugins): # Skip plugin if it doesn't contain the required dictionary # or actually is a proper Python module p = plugin['plugin'] if not hasattr(p, 'pluginProperties'): continue props = p.pluginProperties() root = self.userroot if (plugin['location'] == 'base'): root = self.baseroot else: root = self.userroot i = self.tcPlugins.AppendItem(root, props['name'], 1) if (p.__name__ in self.pluginsDisabled): self.tcPlugins.SetItemImage(i, 2) self.tcPlugins.SetItemTextColour(i, wx.Colour(169, 169, 169)) self.tcPlugins.SetPyData(i, n) self.tcPlugins.SelectItem(i) self.tcPlugins.ExpandAll() wx.EVT_TREE_ITEM_COLLAPSING(self, XRCID('tcPlugins'), self.OnExpandCollapseTree) wx.EVT_TREE_ITEM_EXPANDING(self, XRCID('tcPlugins'), self.OnExpandCollapseTree)
def bind_events(self): self.Bind(EVT_MENU, self.on_file_menu_open_file, id=XRCID('file_menu_open_file')) self.Bind(EVT_MENU, self.on_file_menu_close_window, id=XRCID('file_menu_close_window'))
def Init(self, field): self.field = field self.btn_ok = XRCCTRL(self, 'btn_ok') wx.EVT_BUTTON(self, XRCID('btn_ok'), self.save_and_close) self.btn_cancel = XRCCTRL(self, 'btn_close') wx.EVT_BUTTON(self, XRCID('btn_close'), self.close) self.label_fieldname = XRCCTRL(self, 'label_fieldname') self.label_fieldname.SetLabel(field.get_name()) self.check_isocenter = XRCCTRL(self, 'check_isocenter') target = field.get_target() if len(target) > 0: self.check_isocenter.SetValue(True) self.check_isocenter.Bind(wx.EVT_CHECKBOX, self.on_check_isocenter_changed) self.txt_targetx = XRCCTRL(self, 'txt_targetx') self.txt_targety = XRCCTRL(self, 'txt_targety') self.txt_targetz = XRCCTRL(self, 'txt_targetz') if len(target) > 0: self.txt_targetx.SetValue("%.2f" % (target[0])) self.txt_targety.SetValue("%.2f" % (target[1])) self.txt_targetz.SetValue("%.2f" % (target[2])) else: self.txt_targetx.Enable(False) self.txt_targety.Enable(False) self.txt_targetz.Enable(False) self.txt_gantry = XRCCTRL(self, 'txt_gantry') self.txt_gantry.SetValue("%.2f" % field.get_gantry()) self.txt_couch = XRCCTRL(self, 'txt_couch') self.txt_couch.SetValue("%.2f" % field.get_couch()) self.txt_fwhm = XRCCTRL(self, 'txt_fwhm') self.txt_fwhm.SetValue("%.2f" % field.get_fwhm()) self.txt_zsteps = XRCCTRL(self, 'txt_zsteps') self.txt_zsteps.SetValue("%.2f" % field.get_zsteps()) self.txt_doseextension = XRCCTRL(self, 'txt_doseext') self.txt_doseextension.SetValue("%.2f" % field.get_doseextension()) self.txt_contourextension = XRCCTRL(self, 'txt_contourext') self.txt_contourextension.SetValue("%.2f" % field.get_contourextension()) self.txt_raster1 = XRCCTRL(self, 'txt_raster1') self.txt_raster2 = XRCCTRL(self, 'txt_raster2') raster = field.get_rasterstep() self.txt_raster1.SetValue("%.2f" % raster[0]) self.txt_raster2.SetValue("%.2f" % raster[1]) self.drop_projectile = XRCCTRL(self, 'drop_projectile') self.drop_projectile.SetSelection( self.drop_projectile.GetItems().index(field.projectile))
def Init(self, plugins, pluginsDisabled): """Method called after the panel has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.tcPlugins = XRCCTRL(self, 'tcPlugins') self.panelTreeView = XRCCTRL(self, 'panelTreeView') self.panelProperties = XRCCTRL(self, 'panelProperties') self.lblName = XRCCTRL(self, 'lblName') self.lblAuthor = XRCCTRL(self, 'lblAuthor') self.lblPluginType = XRCCTRL(self, 'lblPluginType') self.lblVersion = XRCCTRL(self, 'lblVersion') self.lblVersionNumber = XRCCTRL(self, 'lblVersionNumber') self.lblDescription = XRCCTRL(self, 'lblDescription') self.checkEnabled = XRCCTRL(self, 'checkEnabled') self.lblMessage = XRCCTRL(self, 'lblMessage') self.btnGetMorePlugins = XRCCTRL(self, 'btnGetMorePlugins') self.btnDeletePlugin = XRCCTRL(self, 'btnDeletePlugin') self.plugins = plugins self.pluginsDisabled = set(pluginsDisabled) # Bind interface events to the proper methods # wx.EVT_BUTTON(self, XRCID('btnDeletePlugin'), self.DeletePlugin) wx.EVT_CHECKBOX(self, XRCID('checkEnabled'), self.OnEnablePlugin) wx.EVT_TREE_ITEM_ACTIVATED(self, XRCID('tcPlugins'), self.OnEnablePlugin) wx.EVT_TREE_SEL_CHANGED(self, XRCID('tcPlugins'), self.OnSelectTreeItem) wx.EVT_TREE_SEL_CHANGING(self, XRCID('tcPlugins'), self.OnSelectRootItem) # Modify the control and font size as needed font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) if guiutil.IsMac(): children = list(self.Children) + \ list(self.panelTreeView.Children) + \ list(self.panelProperties.Children) for control in children: control.SetFont(font) control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) XRCCTRL(self, 'wxID_OK').SetWindowVariant(wx.WINDOW_VARIANT_NORMAL) font.SetWeight(wx.FONTWEIGHT_BOLD) if guiutil.IsMSWindows(): self.tcPlugins.SetPosition((0, 3)) self.panelTreeView.SetWindowStyle(wx.STATIC_BORDER) if (guiutil.IsMac() or guiutil.IsGtk()): self.tcPlugins.SetPosition((-30, 0)) self.panelTreeView.SetWindowStyle(wx.SUNKEN_BORDER) self.lblName.SetFont(font) self.lblMessage.SetFont(font) self.Layout() self.InitPluginList() self.LoadPlugins()
def init_advanved_dose(self): self.drop_projectile = XRCCTRL(self, "drop_projectile") self.drop_projectile.Append("H") self.drop_projectile.Append("C") self.txt_dose_percent = XRCCTRL(self, "txt_dose_percent") wx.EVT_BUTTON(self, XRCID('btn_set_dosepercent'), self.set_dose_percent) wx.EVT_CHOICE(self, XRCID('drop_projectile'), self.on_projectile_changed)
def Init(self, dosecube): self.dosecube = dosecube self.txt_targetdose = XRCCTRL(self, "txt_targetdose") self.txt_targetdose.SetValue("%.1f" % self.dosecube.get_dose()) self.btn_ok = XRCCTRL(self, 'btn_ok') wx.EVT_BUTTON(self, XRCID('btn_ok'), self.save_and_close) self.btn_cancel = XRCCTRL(self, 'btn_close') wx.EVT_BUTTON(self, XRCID('btn_close'), self.close)
def init_files_panel(self): self.txt_ddd = XRCCTRL(self, "txt_ddd") self.txt_ddd.SetValue(self.plan.get_ddd_folder()) self.txt_spc = XRCCTRL(self, "txt_spc") self.txt_spc.SetValue(self.plan.get_spc_folder()) self.txt_sis = XRCCTRL(self, "txt_sis") self.txt_sis.SetValue(self.plan.get_sis_file()) wx.EVT_BUTTON(self, XRCID("btn_ddd"), self.on_btn_ddd_clicked) wx.EVT_BUTTON(self, XRCID("btn_spc"), self.on_btn_spc_clicked) wx.EVT_BUTTON(self, XRCID("btn_sis"), self.on_btn_sis_clicked)
def Init(self): """Method called after the dialog has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.txtDICOMFolder = XRCCTRL(self, 'txtDICOMFolder') self.checkPatientName = XRCCTRL(self, 'checkPatientName') self.txtFirstName = XRCCTRL(self, 'txtFirstName') self.txtLastName = XRCCTRL(self, 'txtLastName') self.checkPatientID = XRCCTRL(self, 'checkPatientID') self.txtPatientID = XRCCTRL(self, 'txtPatientID') self.checkPrivateTags = XRCCTRL(self, 'checkPrivateTags') self.bmpError = XRCCTRL(self, 'bmpError') self.lblDescription = XRCCTRL(self, 'lblDescription') # Bind interface events to the proper methods wx.EVT_BUTTON(self, XRCID('btnFolderBrowse'), self.OnFolderBrowse) wx.EVT_CHECKBOX(self, XRCID('checkPatientName'), self.OnCheckPatientName) wx.EVT_CHECKBOX(self, XRCID('checkPatientID'), self.OnCheckPatientID) wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK) # Set and bold the font of the description label if guiutil.IsMac(): font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetWeight(wx.FONTWEIGHT_BOLD) self.lblDescription.SetFont(font) # Initialize the import location via pubsub pub.subscribe(self.OnImportPrefsChange, 'general.dicom.import_location') pub.sendMessage('preferences.requested.value', 'general.dicom.import_location') # Pre-select the text on the text controls due to a Mac OS X bug self.txtFirstName.SetSelection(-1, -1) self.txtLastName.SetSelection(-1, -1) self.txtPatientID.SetSelection(-1, -1) # Load the error bitmap self.bmpError.SetBitmap(wx.Bitmap(util.GetResourcePath('error.png'))) # Initialize variables self.name = self.txtLastName.GetValue( ) + '^' + self.txtFirstName.GetValue() self.patientid = self.txtPatientID.GetValue() self.privatetags = True
def Init(self, plan): self.plan = plan self.btn_ok = XRCCTRL(self, 'btn_ok') wx.EVT_BUTTON(self, XRCID('btn_ok'), self.save_and_close) self.btn_cancel = XRCCTRL(self, 'btn_close') wx.EVT_BUTTON(self, XRCID('btn_close'), self.close) self.init_general() self.init_trip_panel() self.init_opt_panel() self.init_calculation_panel() self.init_files_panel() self.init_advanved_dose()
def Init(self, parent): self.parent = parent self.notebook = XRCCTRL(self, "notebook") voxelplan_image = self.parent.data.get_images().get_voxelplan() center = [ voxelplan_image.dimx / 2.0 * voxelplan_image.pixel_size, voxelplan_image.dimy / 2.0 * voxelplan_image.pixel_size, voxelplan_image.dimz / 2.0 * voxelplan_image.slice_distance ] self.txt_name = XRCCTRL(self, "txt_name") data = self.parent.data num = len(data.get_vois()) num += 1 self.txt_name.SetValue("ptv %d" % num) self.txt_x = XRCCTRL(self, "txt_x") self.txt_x.SetValue("%.1f" % center[0]) self.txt_y = XRCCTRL(self, "txt_y") self.txt_y.SetValue("%.1f" % center[1]) self.txt_z = XRCCTRL(self, "txt_z") self.txt_z.SetValue("%.1f" % center[2]) # ini cube self.txt_width = XRCCTRL(self, "txt_width") self.txt_width.SetValue("50") self.txt_height = XRCCTRL(self, "txt_height") self.txt_height.SetValue("50") self.txt_depth = XRCCTRL(self, "txt_depth") self.txt_depth.SetValue("50") # ini cylinder self.txt_cylinder_radius = XRCCTRL(self, "txt_cylinder_radius") self.txt_cylinder_radius.SetValue("50") self.txt_cylinder_depth = XRCCTRL(self, "txt_cylinder_depth") self.txt_cylinder_depth.SetValue("40") # ini sphere self.txt_sphere_radius = XRCCTRL(self, "txt_sphere_radius") self.txt_sphere_radius.SetValue("25") wx.EVT_BUTTON(self, XRCID("btn_create"), self.submit) wx.EVT_BUTTON(self, XRCID("btn_cancel"), self.close)
def Init(self, name=None, appname=""): """Method called after the panel has been initialized.""" # Hide the close button on Mac if guiutil.IsMac(): XRCCTRL(self, 'wxID_OK').Hide() # Set window icon else: self.SetIcon(guiutil.get_icon()) # Set the dialog title if name: self.SetTitle(name) # Initialize controls self.notebook = XRCCTRL(self, 'notebook') # Modify the control and font size on Mac for child in self.GetChildren(): guiutil.adjust_control(child) # Bind ui events to the proper methods self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnClose) wx.EVT_BUTTON(self, XRCID('wxID_OK'), self.OnClose) # Initialize variables self.preftemplate = [] self.values = {} self.appname = appname
def DoCreateResource(self): debug.info("[Resource] class %s 's object..." % self.GetName()) # Now create the object if issubclass(self.winclass, wx.Dialog): obj = self.winclass(self.parentwin, self.GetID(), self.GetText('title'), self.GetPosition(), self.GetSize(), self.GetStyle() ) elif issubclass(self.winclass, wx.Frame): obj = self.winclass(self.parentwin, self.GetID(), self.GetText('title'), self.GetPosition(), self.GetSize(), self.GetStyle() ) elif issubclass(self,winclass, wx.Panel): obj = self.winclass(self.parentwin, self.GetID(), self.GetPosition(), self.GetSize(), self.GetStyle(), self.GetName(), ) # These two things should be done in either case: # Set standard window attributes self.SetupWindow(obj) # Create any child windows of this node self.CreateChildren(obj) # Create IDs for id in self.ids: setattr(obj, id, XRCID(id)) setattr(obj, 'obj_'+id, self.parentwin.FindWindowById(XRCID(id))) # Call object init obj.init(*self.args, **self.kwargs) self.obj = obj return obj
def Init(self, voi): self.voi = voi wx.EVT_BUTTON(self, XRCID('btn_ok'), self.save_and_close) wx.EVT_BUTTON(self, XRCID('btn_close'), self.close) self.label_name = XRCCTRL(self, "label_name") self.label_name.SetLabel(voi.get_name()) self.txt_dose = XRCCTRL(self, "txt_dose") self.txt_dose.SetValue("%.2f" % (voi.get_dose())) self.check_target = XRCCTRL(self, "check_target") self.check_target.SetValue(voi.is_target()) self.check_target.Bind(wx.EVT_CHECKBOX, self.on_check_target_changed) self.check_oar = XRCCTRL(self, "check_oar") self.check_oar.SetValue(voi.is_oar()) self.check_oar.Bind(wx.EVT_CHECKBOX, self.on_check_oar_changed) self.txt_max_dose_fraction = XRCCTRL(self, "txt_max_dose_fraction") self.txt_max_dose_fraction.SetValue("%.2f" % (voi.get_max_dose_fraction())) self.txt_max_dose_fraction.Enable(False) self.txt_dose.Enable(False) if voi.is_target(): self.check_oar.Enable(False) self.txt_dose.Enable(True) if voi.is_oar(): self.txt_max_dose_fraction.Enable(True) self.check_target.Enable(False) self.txt_hu_value = XRCCTRL(self, "txt_hu_value") self.txt_hu_offset = XRCCTRL(self, "txt_hu_offset") if not voi.get_hu_value() is None: self.txt_hu_value.SetValue("%d" % voi.get_hu_value()) if not voi.get_hu_offset() is None: self.txt_hu_offset.SetValue("%d" % voi.get_hu_offset()) self.drop_projectile = XRCCTRL(self, "drop_projectile") self.drop_projectile.Append("H") self.drop_projectile.Append("C") self.txt_dose_percent = XRCCTRL(self, "txt_dose_percent") wx.EVT_BUTTON(self, XRCID('btn_set_dosepercent'), self.set_dose_percent) wx.EVT_CHOICE(self, XRCID('drop_projectile'), self.on_projectile_changed)
def Init(self, tripexecuter): self.tripexecuter = tripexecuter self.tripexecuter.add_log_listener(self) self.txt_log = XRCCTRL(self, "txt_log") wx.EVT_BUTTON(self, XRCID("btn_ok"), self.close) self.btn_ok = XRCCTRL(self, "btn_ok") self.btn_ok.Enable(False) self.check_close = XRCCTRL(self, "check_close")
def Init(self, plan): self.output_path = '' self.drop_type = XRCCTRL(self, "drop_type") self.txt_prefix = XRCCTRL(self, "txt_prefix") self.txt_prefix.SetValue(plan.get_name()) self.label_folder = XRCCTRL(self, "label_folder") wx.EVT_BUTTON(self, XRCID("btn_cancel"), self.close) wx.EVT_BUTTON(self, XRCID("btn_browse"), self.browse_folder) wx.EVT_BUTTON(self, XRCID("btn_generate"), self.generate) self.plan = plan pub.subscribe(self.on_patient_updated, "patient.loaded") pub.subscribe(self.on_export_voxelplan_changed, "general.export.voxelplan") pub.sendMessage("settings.value.request", "general.export.voxelplan") pub.sendMessage("patient.request", None)
def Init(self, plan): self.plan = plan self.path = "~/" self.output_path = "" self.checkbox_vois = XRCCTRL(self, "checkbox_vois") wx.EVT_LISTBOX(self, XRCID("checkbox_vois"), self.selected_changed) wx.EVT_BUTTON(self, XRCID("btn_ok"), self.save_and_close) wx.EVT_BUTTON(self, XRCID("btn_cancel"), self.close) wx.EVT_BUTTON(self, XRCID("btn_reset"), self.reset) self.lbl_path = XRCCTRL(self, "lbl_path") self.txt_value = XRCCTRL(self, "txt_value") wx.EVT_TEXT(self, XRCID("txt_value"), self.text_value_changed) pub.subscribe(self.path_changed, "general.export.cube_export_path") pub.sendMessage("settings.value.request", "general.export.cube") pub.subscribe(self.patient_data_updated, "patient.loaded") pub.sendMessage("patient.request", {}) for voi in plan.get_vois(): self.checkbox_vois.Append(voi.get_name())
def init(self): self.coords = XRCCTRL(self, 'txt_coords') self.color = XRCCTRL(self, 'txt_color') self.scroll = XRCCTRL(self, 'box_scroll') self.image = XRCCTRL(self, 'bmp_image') self.image.Bind(wx.EVT_LEFT_DOWN, self.on_left_down) self.image.Bind(wx.EVT_RIGHT_DOWN, self.on_right_down) #self.update_image() self.which = XRCCTRL(self, 'txt_which') self.update_which() # button handlers for btn in 'btn_first btn_prev btn_next btn_last'.split(): self.Bind(wx.EVT_BUTTON, self.on_cursor_button, id=XRCID(btn)) # menu handlers self.Bind(wx.EVT_MENU, self.on_exit, id=XRCID('cmd_exit')) self.Bind(wx.EVT_MENU, self.on_open_file, id=XRCID('cmd_open_file')) self.Bind(wx.EVT_MENU, self.on_open_dir, id=XRCID('cmd_open_dir')) self.Bind(wx.EVT_CLOSE, self.on_close_window) # -- manually add pyshell panel = XRCCTRL(self, 'shell_panel') self.locals = { 'self': self, 'wx': wx, 'hook': lambda: None, 'gc': self.get_dc() } self.shell = py.shell.Shell(panel, locals=self.locals) sizer = wx.BoxSizer() sizer.Add(self.shell, 4, wx.EXPAND) self.shell.SetFocus() panel.SetSizer(sizer) sizer.Fit(panel)
def bind_event_handler(frame, controller=None): import wx from wx.xrc import XRCID if controller is None: controller = frame for name in dir(controller): obj = getattr(controller, name) if hasattr(obj, attr_key): for event_info in getattr(obj, attr_key): if event_info.id is None: frame.Bind(event_info.event, obj) else: frame.Bind(event_info.event, obj, id=XRCID(event_info.id))
def __getattr__(self, name): """Returns a new wx-Id for each new string <name>. If the same name is given twice, the same id is returned. If the name is in the XRC id-table its value there will be returned """ try: return XRCID(name) except: try: return self._poolmap[name] except KeyError: id = wx.NewId() self._poolmap[name] = id return id
def on_field_view_ready(self, dispatcher, view): assert view is not None view.Bind(EVT_MENU, self.imp.on_addr_rel, id=XRCID('field_menu_address_relative')) view.Bind(EVT_MENU, self.imp.on_addr_abs, id=XRCID('field_menu_address_absolute')) view.Bind(EVT_MENU, self.imp.on_addr_hex, id=XRCID('field_menu_address_base_hex')) view.Bind(EVT_MENU, self.imp.on_addr_dec, id=XRCID('field_menu_address_base_dec')) view.Bind(EVT_MENU, self.imp.on_dump_to_disk, id=XRCID('field_menu_dump_to_disk')) view.Bind(EVT_MENU, self.imp.on_parse_substream, id=XRCID('field_menu_parse_substream')) view.Bind(EVT_MENU, self.imp.on_open_window_here, id=XRCID('field_menu_open_window_here'))
def bindall(self, obj): for func_name, args, keys in self.binds[hash(self)]: keys = dict(keys) if keys.has_key('event'): event = keys['event'] del keys['event'] else: event = args[0] args = list(args[1:]) control = obj if keys.has_key('id'): if isinstance(keys['id'], str): keys['id'] = XRCID(keys['id']) if keys.has_key('control'): control = keys['control'] if isinstance(control, str): control = XRCCTRL(obj, control) del keys['control'] control.Bind(event, getattr(obj, func_name), *args, **keys)
def init_trip_panel(self): self.drop_location = XRCCTRL(self, "drop_location") if self.plan.is_remote(): self.drop_location.SetSelection(1) self.txt_working_dir = XRCCTRL(self, "txt_working_dir") self.txt_working_dir.SetValue(self.plan.get_working_dir()) wx.EVT_BUTTON(self, XRCID('btn_working_dir'), self.on_browse_working_dir) self.txt_username = XRCCTRL(self, "txt_username") self.txt_username.SetValue(self.plan.get_username()) self.txt_password = XRCCTRL(self, "txt_password") self.txt_password.SetValue(self.plan.get_password()) self.txt_server = XRCCTRL(self, "txt_server") self.txt_server.SetValue(self.plan.get_server())
def Init(self, res): """Method called after the panel has been initialized.""" # Initialize the panel controls self.choiceDICOM = XRCCTRL(self, 'choiceDICOM') self.tlcTreeView = DICOMTree(self) res.AttachUnknownControl('tlcTreeView', self.tlcTreeView, self) # Bind interface events to the proper methods self.Bind(wx.EVT_CHOICE, self.OnLoadTree, id=XRCID('choiceDICOM')) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) # Decrease the font size on Mac font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) if guiutil.IsMac(): font.SetPointSize(10) self.tlcTreeView.SetFont(font) # Set up pubsub pub.subscribe(self.OnUpdatePatient, 'patient.updated.raw_data')
def __init__(self, parent, id, title, res): # Initialize logging logger = logging.getLogger('dicompyler') # Configure the exception hook to process threads as well self.InstallThreadExcepthook() # Remap the exception hook so that we can log and display exceptions def LogExcepthook(*exc_info): # Log the exception text = "".join(traceback.format_exception(*exc_info)) logger.error("Unhandled exception: %s", text) pub.sendMessage('logging.exception', text) sys.excepthook = LogExcepthook # Modify the logging system from pydicom to capture important messages pydicom_logger = logging.getLogger('pydicom') for l in pydicom_logger.handlers: pydicom_logger.removeHandler(l) # Add file logger logpath = os.path.join(guiutil.get_data_dir(), 'logs') if not os.path.exists(logpath): os.makedirs(logpath) self.fh = logging.handlers.RotatingFileHandler(os.path.join( logpath, 'dicompyler.log'), maxBytes=524288, backupCount=7) self.fh.setFormatter( logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s')) self.fh.setLevel(logging.WARNING) logger.addHandler(self.fh) pydicom_logger.addHandler(self.fh) # Add console logger if not frozen if not util.main_is_frozen(): self.ch = logging.StreamHandler() self.ch.setFormatter( logging.Formatter('%(levelname)s: %(message)s')) self.ch.setLevel(logging.WARNING) logger.addHandler(self.ch) pydicom_logger.addHandler(self.ch) # Otherwise if frozen, send stdout/stderror to /dev/null since # logging the messages seems to cause instability due to recursion else: devnull = open(os.devnull, 'w') sys.stdout = devnull sys.stderr = devnull # Set the window size if guiutil.IsMac(): size = (900, 700) else: size = (850, 625) wx.Frame.__init__(self, parent, id, title, pos=wx.DefaultPosition, size=size, style=wx.DEFAULT_FRAME_STYLE) # Set up the status bar self.sb = self.CreateStatusBar(3) # set up resource file and config file self.res = res # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Load the main panel for the program self.panelGeneral = self.res.LoadPanel(self, 'panelGeneral') # Initialize the General panel controls self.notebook = XRCCTRL(self, 'notebook') self.notebookTools = XRCCTRL(self, 'notebookTools') self.lblPlanName = XRCCTRL(self, 'lblPlanName') self.lblRxDose = XRCCTRL(self, 'lblRxDose') self.lblPatientName = XRCCTRL(self, 'lblPatientName') self.lblPatientID = XRCCTRL(self, 'lblPatientID') self.lblPatientGender = XRCCTRL(self, 'lblPatientGender') self.lblPatientDOB = XRCCTRL(self, 'lblPatientDOB') self.choiceStructure = XRCCTRL(self, 'choiceStructure') self.lblStructureVolume = XRCCTRL(self, 'lblStructureVolume') self.lblStructureMinDose = XRCCTRL(self, 'lblStructureMinDose') self.lblStructureMaxDose = XRCCTRL(self, 'lblStructureMaxDose') self.lblStructureMeanDose = XRCCTRL(self, 'lblStructureMeanDose') self.cclbStructures = guiutil.ColorCheckListBox( self.notebookTools, 'structure') self.cclbIsodoses = guiutil.ColorCheckListBox(self.notebookTools, 'isodose') # Modify the control and font size on Mac controls = [self.notebookTools, self.choiceStructure] if guiutil.IsMac(): font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetPointSize(10) for control in controls: control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) control.SetFont(font) # Setup the layout for the frame mainGrid = wx.BoxSizer(wx.VERTICAL) hGrid = wx.BoxSizer(wx.HORIZONTAL) if guiutil.IsMac(): hGrid.Add(self.panelGeneral, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE, border=4) else: hGrid.Add(self.panelGeneral, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE) mainGrid.Add(hGrid, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE) # Load the menu for the frame menuMain = self.res.LoadMenuBar('menuMain') # If we are running on Mac OS X, alter the menu location if guiutil.IsMac(): wx.App_SetMacAboutMenuItemId(XRCID('menuAbout')) wx.App_SetMacPreferencesMenuItemId(XRCID('menuPreferences')) wx.App_SetMacExitMenuItemId(XRCID('menuExit')) # Set the menu as the default menu for this frame self.SetMenuBar(menuMain) # Setup Tools menu self.menuShowLogs = menuMain.FindItemById( XRCID('menuShowLogs')).GetMenu() self.menuPlugins = menuMain.FindItemById( XRCID('menuPluginManager')).GetMenu() # Setup Import menu self.menuImport = menuMain.FindItemById( XRCID('menuImportPlaceholder')).GetMenu() self.menuImport.Delete( menuMain.FindItemById(XRCID('menuImportPlaceholder')).GetId()) self.menuImportItem = menuMain.FindItemById(XRCID('menuImport')) self.menuImportItem.Enable(False) # Setup Export menu self.menuExport = menuMain.FindItemById( XRCID('menuExportPlaceholder')).GetMenu() self.menuExport.Delete( menuMain.FindItemById(XRCID('menuExportPlaceholder')).GetId()) self.menuExportItem = menuMain.FindItemById(XRCID('menuExport')) self.menuExportItem.Enable(False) # Bind menu events to the proper methods wx.EVT_MENU(self, XRCID('menuOpen'), self.OnOpenPatient) wx.EVT_MENU(self, XRCID('menuExit'), self.OnClose) wx.EVT_MENU(self, XRCID('menuPreferences'), self.OnPreferences) wx.EVT_MENU(self, XRCID('menuShowLogs'), self.OnShowLogs) wx.EVT_MENU(self, XRCID('menuPluginManager'), self.OnPluginManager) wx.EVT_MENU(self, XRCID('menuAbout'), self.OnAbout) wx.EVT_MENU(self, XRCID('menuHomepage'), self.OnHomepage) wx.EVT_MENU(self, XRCID('menuLicense'), self.OnLicense) # Load the toolbar for the frame toolbarMain = self.res.LoadToolBar(self, 'toolbarMain') self.SetToolBar(toolbarMain) self.toolbar = self.GetToolBar() # Setup main toolbar controls folderbmp = wx.Bitmap(util.GetResourcePath('folder_user.png')) self.maintools = [{ 'label': "Open Patient", 'bmp': folderbmp, 'shortHelp': "Open Patient...", 'eventhandler': self.OnOpenPatient }] for m, tool in enumerate(self.maintools): self.toolbar.AddLabelTool(m + 1, tool['label'], tool['bmp'], shortHelp=tool['shortHelp']) self.Bind(wx.EVT_TOOL, tool['eventhandler'], id=m + 1) self.toolbar.Realize() # Bind interface events to the proper methods wx.EVT_CHOICE(self, XRCID('choiceStructure'), self.OnStructureSelect) self.Bind(wx.EVT_ACTIVATE, self.OnActivate) self.Bind(wx.EVT_CLOSE, self.OnClose) self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged) # Events to work around a focus bug in Windows self.notebook.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebook.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.notebookTools.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebookTools.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.SetSizer(mainGrid) self.Layout() #Set the Minumum size self.SetMinSize(size) self.Centre(wx.BOTH) # Initialize the welcome notebook tab panelWelcome = self.res.LoadPanel(self.notebook, 'panelWelcome') self.notebook.AddPage(panelWelcome, 'Welcome') # Set the version on the welcome notebook tab XRCCTRL(self, 'lblVersion').SetLabel('Version ' + __version__) # Initialize the tools notebook self.notebookTools.AddPage(self.cclbStructures, 'Structures') self.notebookTools.AddPage(self.cclbIsodoses, 'Isodoses') # Create the data folder datapath = guiutil.get_data_dir() if not os.path.exists(datapath): os.mkdir(datapath) # Initialize the preferences if guiutil.IsMac(): self.prefmgr = preferences.PreferencesManager(parent=None, appname='dicompyler') else: self.prefmgr = preferences.PreferencesManager(parent=None, appname='dicompyler', name='Options') sp = wx.StandardPaths.Get() self.generalpreftemplate = [{ 'DICOM Import Settings': [{ 'name': 'Import Location', 'type': 'choice', 'values': ['Remember Last Used', 'Always Use Default'], 'default': 'Remember Last Used', 'callback': 'general.dicom.import_location_setting' }, { 'name': 'Default Location', 'type': 'directory', 'default': unicode(sp.GetDocumentsDir()), 'callback': 'general.dicom.import_location' }] }, { 'Plugin Settings': [{ 'name': 'User Plugins Location', 'type': 'directory', 'default': unicode(os.path.join(datapath, 'plugins')), 'callback': 'general.plugins.user_plugins_location', 'restart': True }] }, { 'Calculation Settings': [{ 'name': 'DVH Calculation', 'type': 'choice', 'values': ['Use RT Dose DVH if Present', 'Always Recalculate DVH'], 'default': 'Use RT Dose DVH if Present', 'callback': 'general.calculation.dvh_recalc' }] }, { 'Advanced Settings': [{ 'name': 'Enable Detailed Logging', 'type': 'checkbox', 'default': False, 'callback': 'general.advanced.detailed_logging' }] }] self.preftemplate = [{'General': self.generalpreftemplate}] pub.sendMessage('preferences.updated.template', self.preftemplate) # Initialize variables self.ptdata = {} # Set up pubsub pub.subscribe(self.OnLoadPatientData, 'patient.updated.raw_data') pub.subscribe(self.OnStructureCheck, 'colorcheckbox.checked.structure') pub.subscribe(self.OnStructureUncheck, 'colorcheckbox.unchecked.structure') pub.subscribe(self.OnIsodoseCheck, 'colorcheckbox.checked.isodose') pub.subscribe(self.OnIsodoseUncheck, 'colorcheckbox.unchecked.isodose') pub.subscribe(self.OnUpdatePlugins, 'general.plugins.user_plugins_location') pub.subscribe(self.OnUpdatePreferences, 'general') pub.subscribe(self.OnUpdateStatusBar, 'main.update_statusbar') pub.subscribe(self.OnOpenPatient, 'dicomgui.show') # Send a message to the logging system to turn on/off detailed logging pub.sendMessage('preferences.requested.value', 'general.advanced.detailed_logging') # Create the default user plugin path self.userpluginpath = os.path.join(datapath, 'plugins') if not os.path.exists(self.userpluginpath): os.mkdir(self.userpluginpath) # Load and initialize plugins self.plugins = [] self.pluginsDisabled = [] pub.sendMessage('preferences.requested.value', 'general.plugins.user_plugins_location') pub.sendMessage('preferences.requested.value', 'general.calculation.dvh_recalc') pub.sendMessage('preferences.requested.value', 'general.plugins.disabled_list') pub.sendMessage('preferences.requested.values', 'general.window')
def Init(self, structures, dvhs): """Method called after panel has ben initialized.""" # Initialize variables self.dvhs = {} # raw dvhs from initial DICOM data self.dvhdata = {} # dict of dvh constraint functions self.structures = structures self.dvhs = dvhs # Setup toolbar controls #drawingstyles = ['Solid', 'Transparent', 'Dot', 'Dash', 'Dot Dash'] #self.tools = [] self.widgetDict = { 'choiceOptic': ['Optic', 'OpticMax'], 'choiceCochlea': ['CochleaMax'], 'choiceBrainstem': ['Brainstem', 'BrainstemMax'], 'choiceSpinal': ['Spinal1', 'Spinal2', 'SpinalMax'], 'choiceCauda': ['Cauda', 'CaudaMax'], 'choiceSacral': ['Sacral', 'SacralMax'], 'choiceEsophagus': ['Esophagus', 'EsophagusMax'], 'choiceBrachial': ['Brachial', 'BrachialMax'], 'choiceHeart': ['Heart', 'HeartMax'], 'choiceGreatVessels': ['GreatVessels', 'GreatVesselsMax'], 'choiceTrachea': ['Trachea', 'TracheaMax'], 'choiceSmallBronchus': ['SmallBronchus', 'SmallBronchusMax'], 'choiceRib': ['Rib', 'RibMax'], 'choiceSkin': ['Skin', 'SkinMax'], 'choiceStomach': ['Stomach', 'StomachMax'], 'choiceBowel': ['Bowel', 'BowelMax'], 'choiceRenalHilum': ['RenalHilum'], 'choiceLungs': ['Lungs1', 'Lungs2'], 'choiceLiver': ['Liver'], 'choiceRenalCortex': ['RenalCortex'] } self.volDict = { 1: 'Optic', 2: 'Brainstem', 3: 'Spinal1', 4: 'Spinal2', 5: 'Cauda', 6: 'Sacral', 7: 'Esophagus', 8: 'Brachial', 9: 'Heart', 10: 'GreatVessels', 11: 'Trachea', 12: 'SmallBronchus', 13: 'Rib', 14: 'Skin', 15: 'Stomach', 16: 'Bowel', 17: 'RenalHilum', 18: 'Lungs1', 19: 'Lungs2', 20: 'Liver', 21: 'RenalCortex' } self.initialGuessDict = { 'choiceOptic': ['optic pathway', 'optic structures'], 'choiceCochlea': ['cochlea'], 'choiceBrainstem': ['brainstem'], 'choiceSpinal': ['spinal cord', 'cord'], 'choiceCauda': ['cauda', 'cauda equina'], 'choiceEsophagus': ['esophagus'], 'choiceBrachial': ['brachial plexus'], 'choiceHeart': ['heart'], 'choiceGreatVessels': ['great vessels', 'greater vessels', 'gv'], 'choiceTrachea': ['trachea', 'trachea/bronchus', 'bronchus', 'large bronchus'], 'choiceSmallBronchus': ['small bronchus', 'smaller bronchus'], 'choiceRib': ['rib', 'ribs'], 'choiceSkin': [ 'skin', 'skin 5mm', 'skin (5mm)', 'skin(5mm)', 'skin(0.5cm)', 'skin (0.5cm)' ], 'choiceStomach': ['stomach'], 'choiceBowel': ['bowel'], 'choiceRenalHilum': ['renal hilum'], 'choiceLungs': ['lungs', 'total lung', 'total lungs', 'lung'], 'choiceLiver': ['liver'], 'choiceRenalCortex': ['renal cortex'] } "Tolerances from TG-101 table." "Format (serial) [volume, limit(1fx), limit(2fx), limit(3fx), limit(4fx), limit(5fx)]" "Format (parall) [thresh, limit(1fx), limit(2fx), limit(3fx), limit(4fx), limit(5fx)]" self.toleranceOptic = [0.2, 8.0, 11.7, 15.3, 19.2, 23.0] self.toleranceOpticMax = [0, 10, 13.7, 17.4, 21.2, 25] self.toleranceCochleaMax = [0, 9, 13.1, 17.1, 21.1, 25] self.toleranceBrainstem = [0.5, 10, 14, 18, 20.5, 23] self.toleranceBrainstemMax = [0, 15, 19.1, 23.1, 27.1, 31] self.toleranceSpinal1 = [0.35, 10, 14, 18, 20.5, 23] self.toleranceSpinal2 = [1.2, 7, 9.7, 12.3, 13.4, 14.5] self.toleranceSpinalMax = [0, 14, 18, 21.9, 26, 30] self.toleranceCauda = [5, 14, 18, 21.9, 26, 30] self.toleranceCaudaMax = [0, 16, 20, 24, 28, 32] self.toleranceSacral = [5, 14.4, 18.5, 22.5, 26.3, 30] self.toleranceSacralMax = [0, 16, 20, 24, 28, 32] self.toleranceEsophagus = [5, 11.9, 14.8, 17.7, 18.6, 19.5] self.toleranceEsophagusMax = [0, 15.4, 20.3, 25.2, 30.1, 35] self.toleranceBrachial = [3, 14, 17.2, 20.4, 23.7, 27] self.toleranceBrachialMax = [0, 17.5, 20.8, 24, 27.3, 30.5] self.toleranceHeart = [15, 16, 20, 24, 28, 32] self.toleranceHeartMax = [0, 22, 26, 30, 34, 38] self.toleranceGreatVessels = [10, 31, 35, 39, 43, 47] self.toleranceGreatVesselsMax = [0, 37, 41, 45, 49, 53] self.toleranceTrachea = [4, 10.5, 12.8, 15, 15.8, 16.5] self.toleranceTracheaMax = [0, 20.2, 25.1, 30, 35, 40] self.toleranceSmallBronchus = [0.5, 12.4, 15.7, 18.9, 20, 21] self.toleranceSmallBronchusMax = [0, 13.3, 18.2, 23.1, 28.1, 33] self.toleranceRib = [1, 22, 25.4, 28.8, 31.9, 35] self.toleranceRibMax = [0, 30, 33.5, 36.9, 40, 43] self.toleranceSkin = [10, 23, 26.5, 30, 33.3, 36.5] self.toleranceSkinMax = [0, 26, 29.5, 33, 36.3, 39.5] self.toleranceStomach = [10, 11.2, 13.9, 16.5, 17.3, 18] self.toleranceStomachMax = [0, 12.4, 17.3, 22.2, 27.1, 32] self.toleranceBowel = [5, 11.9, 14.8, 17.7, 18.6, 19.5] self.toleranceBowelMax = [0, 15.4, 20.3, 25.2, 30.1, 35] self.toleranceRenalHilum = ['66.6%', 10.6, 14.6, 18.6, 20.8, 23] self.toleranceLungs1 = ['> 1500', 7, 9.3, 11.6, 12.1, 12.5] self.toleranceLungs2 = ['> 1000', 7.4, 9.9, 12.4, 13, 13.5] self.toleranceLiver = ['> 700', 9.1, 14.2, 19.2, 20.1, 21] self.toleranceRenalCortex = ['> 200', 8.4, 12.2, 16, 16.8, 17.5] # Initialize the Analysis fractionation control self.choiceFractions = XRCCTRL(self, 'choiceFractions') # Volumes defined per fraction/Organ # Doses defined per fraction/Organ (Critical Volume/Threshold organs) # NOTE: Lungs, Liver, and RenalCortex are actually THRESHOLDS (in Gy), # NOT volumes. This was only done for a simpler for_loop. # See columns on GUI. # Look up GUI Column 2 values for i, organName in self.volDict.iteritems(): volName = 'vol' + organName setattr(self, volName, XRCCTRL(self, volName)) # Define structure lists (choices) and dose limits (in cGy) for organ for choiceName, organList in self.widgetDict.iteritems(): #i.e. self.choiceOptic (combobox) setattr(self, choiceName, XRCCTRL(self, choiceName)) for organName in organList: limitName = 'limit' + organName # TG limit values planName = 'plan' + organName # Dose values obtained from plan imgName = 'img' + organName #Image box indicator # i.e. self.limitOptic setattr(self, limitName, XRCCTRL(self, limitName)) # i.e. self.planOptic setattr(self, planName, XRCCTRL(self, planName)) # i.e. self.imgOptic setattr(self, imgName, XRCCTRL(self, imgName)) img = os.path.join(os.path.dirname(__file__), 'transparent.png') img = wx.Image(img, wx.BITMAP_TYPE_ANY) self.imgTransparent = wx.BitmapFromImage(img) img = os.path.join(os.path.dirname(__file__), 'check.png') img = wx.Image(img, wx.BITMAP_TYPE_ANY) self.imgCheck = wx.BitmapFromImage(img) img = os.path.join(os.path.dirname(__file__), 'flag.png') img = wx.Image(img, wx.BITMAP_TYPE_ANY) self.imgFlag = wx.BitmapFromImage(img) # Bind ui events to the proper methods wx.EVT_COMBOBOX(self, XRCID('choiceFractions'), self.ReadTolerances) wx.EVT_COMBOBOX(self, XRCID('choiceOptic'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceCochlea'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceBrainstem'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceSpinal'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceCauda'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceSacral'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceEsophagus'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceBrachial'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceHeart'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceGreatVessels'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceTrachea'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceSmallBronchus'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceRib'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceSkin'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceStomach'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceBowel'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceRenalHilum'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceLungs'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceLiver'), self.OnComboOrgan) wx.EVT_COMBOBOX(self, XRCID('choiceRenalCortex'), self.OnComboOrgan) self.SetStructureChoices() self.InitialGuessCombobox() self.DisableChoices()
def Init(self, res): """Method called after the panel has been initialized.""" self.guiDVH = guidvh.guiDVH(self) res.AttachUnknownControl("panelDVH", self.guiDVH.panelDVH, self) # Initialize the Constraint selector controls self.lblType = XRCCTRL(self, "lblType") self.choiceConstraint = XRCCTRL(self, "choiceConstraint") self.txtConstraint = XRCCTRL(self, "txtConstraint") self.sliderConstraint = XRCCTRL(self, "sliderConstraint") self.lblResultType = XRCCTRL(self, "lblResultType") self.lblConstraintUnits = XRCCTRL(self, "lblConstraintUnits") self.lblConstraintTypeUnits = XRCCTRL(self, "lblConstraintTypeUnits") # Initialize the result labels self.lblConstraintType = XRCCTRL(self, "lblConstraintType") self.lblResultDivider = XRCCTRL(self, "lblResultDivider") self.lblConstraintPercent = XRCCTRL(self, "lblConstraintPercent") # Modify the control and font size on Mac controls = [ self.lblType, self.choiceConstraint, self.sliderConstraint, self.lblResultType, self.lblConstraintUnits, self.lblConstraintPercent, self.lblConstraintType, self.lblConstraintTypeUnits, self.lblResultDivider, ] # Add children of composite controls to modification list compositecontrols = [self.txtConstraint] for control in compositecontrols: for child in control.GetChildren(): controls.append(child) # Add the constraint static box to the modification list controls.append(self.lblType.GetContainingSizer().GetStaticBox()) if guiutil.IsMac(): for control in controls: control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) # Adjust the control size for the result value labels te = self.lblType.GetTextExtent("0") self.lblConstraintUnits.SetMinSize((te[0] * 10, te[1])) self.lblConstraintPercent.SetMinSize((te[0] * 6, te[1])) self.Layout() # Bind ui events to the proper methods self.Bind(wx.EVT_CHOICE, self.OnToggleConstraints, id=XRCID("choiceConstraint")) self.Bind(wx.EVT_SPINCTRL, self.OnChangeConstraint, id=XRCID("txtConstraint")) self.Bind( wx.EVT_COMMAND_SCROLL_THUMBTRACK, self.OnChangeConstraint, id=XRCID("sliderConstraint"), ) self.Bind( wx.EVT_COMMAND_SCROLL_CHANGED, self.OnChangeConstraint, id=XRCID("sliderConstraint"), ) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) # Initialize variables self.structures = {} # structures from initial DICOM data self.checkedstructures = {} # structures that need to be shown self.dvhs = {} # raw dvhs from initial DICOM data self.dvharray = {} # dict of dvh data processed from dvhdata self.dvhscaling = {} # dict of dvh scaling data self.plan = {} # used for rx dose self.structureid = 1 # used to indicate current constraint structure # Set up pubsub pub.subscribe(self.OnUpdatePatient, "patient.updated.parsed_data") pub.subscribe(self.OnStructureCheck, "structures.checked") pub.subscribe(self.OnStructureSelect, "structure.selected")