def rectangular_roi_traitsui(obj, **kwargs): view = tu.View( tu.Group( tu.Item( 'left', label='Left', format_str='%5g', ), tu.Item( 'right', label='Right', format_str='%5g', ), tu.Item( 'top', label='Top', format_str='%5g', ), tu.Item( 'bottom', label='Bottom', format_str='%5g', ), ), ) return obj, {"view": view}
class FileSelectedFrame(ta.HasTraits): """ Frame for current files selected """ file_list = ta.List(ta.Str, []) Add_File = ta.Button() Add_Folder = ta.Button() Undo_Add = ta.Button() view = tua.View(tua.Item('file_list'), tua.Item('Add_File', show_label=False), tua.Item('Add_Folder', show_label=False), tua.Item('Undo_Add', show_label=False), resizable=True) def _Add_File_fired(self): global select_files self.file_list.append(select_files.file_name) def _Add_Folder_fired(self): global select_files self.file_list += GetAllPDF(select_files.file_directory) def _Undo_Add_fired(self): del self.file_list[-1]
class CrossSection(BMCSLeafNode, RInputRecord): '''Parameters of the pull-out cross section ''' node_name = 'cross-section' R_m = tr.Float(20, CS=True, input=True, unit=r'$\mathrm{mm}$', symbol=r'R_\mathrm{m}', auto_set=False, enter_set=True, desc='matrix area') R_f = tr.Float(1.0, CS=True, input=True, unit='$\\mathrm{mm}$', symbol='R_\mathrm{f}', auto_set=False, enter_set=True, desc='reinforcement area') P_b = tr.Property(unit='$\\mathrm{mm}$', symbol='p_\mathrm{b}', desc='perimeter of the bond interface', depends_on='R_f') @tr.cached_property def _get_P_b(self): return 2 * np.pi * self.R_f view = ui.View(ui.Item('R_m'), ui.Item('R_f'), ui.Item('P_b', style='readonly')) tree_view = view
class AutoRefreshDialog(traits.HasTraits): minutes = traits.Float(1.0) autoRefreshBool = traits.Bool() emailAlertBool = traits.Bool(False) soundAlertBool = traits.Bool(False) linesOfDataFrame = traits.Range(1, 10) alertCode = traits.Code( DEFAULT_ALERT_CODE, desc="python code for finding alert worthy elements") basicGroup = traitsui.Group("minutes", "autoRefreshBool") alertGroup = traitsui.VGroup( traitsui.HGroup(traitsui.Item("emailAlertBool"), traitsui.Item("soundAlertBool")), traitsui.Item("linesOfDataFrame", visible_when="emailAlertBool or soundAlertBool"), traitsui.Item("alertCode", visible_when="emailAlertBool or soundAlertBool")) traits_view = traitsui.View(traitsui.VGroup(basicGroup, alertGroup), title="auto refresh", buttons=[OKButton], kind='livemodal', resizable=True)
class EntryBlock(traits.HasTraits): fieldName = traits.String("fieldName",desc = "describes what the information to be entered in the text block is referring to") textBlock = traits.String() commitButton = traits.Button("save",desc="commit information in text block to logFile") traits_view = traitsui.View(traitsui.VGroup( traitsui.Item("fieldName",show_label=False, style="readonly"), traitsui.Item("textBlock",show_label=False, style="custom"), traitsui.Item("commitButton",show_label=False), show_border=True, label="information" )) def __init__(self, **traitsDict): """user supplies arguments in init to supply class attributes defined above """ super(EntryBlock,self).__init__(**traitsDict) def _commitButton_fired(self): logger.info("saving %s info starting" % self.fieldName) timeStamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") blockDelimiterStart = "__"+self.fieldName+"__<start>" blockDelimiterEnd = "__"+self.fieldName+"__<end>" fullString = "\n"+blockDelimiterStart+"\n"+timeStamp+"\n"+self.textBlock+"\n"+blockDelimiterEnd+"\n" with open(self.commentFile, "a+") as writeFile: writeFile.write(fullString) logger.info("saving %s info finished" % self.fieldName) def clearTextBlock(self): self.textBlock = ""
class Something(tr.HasTraits): txt_file_name = tr.File openTxt = tr.Button('Open...') a = tr.Int(20, auto_set=False, enter_set=True, input=True) b = tr.Float(20, auto_set=False, enter_set=True, input=True) @tr.on_trait_change('+input') def _handle_input_change(self): print('some input parameter changed') self.input_event = True input_event = tr.Event def _some_event_changed(self): print('input happend') def _openTxt_fired(self): print('do something') print(self.txt_file_name) traits_view = ui.View( ui.VGroup( ui.HGroup( ui.Item('openTxt', show_label=False), ui.Item('txt_file_name', width=200), ui.Item('a') ), ) )
def line2d_roi_traitsui(obj, **kwargs): view = tu.View( tu.Group( tu.Item( 'x1', label='x1', format_str='%5g', ), tu.Item( 'y1', label='y1', format_str='%5g', ), tu.Item( 'x2', label='x2', format_str='%5g', ), tu.Item( 'y2', label='y2', format_str='%5g', ), tu.Item( 'linewidth', label='linewidth', format_str='%5g', ), ), ) return obj, {"view": view}
class AxisSelector(traits.HasTraits): """here we select what axes the user should use when plotting this data """ masterList = traits.List masterListWithNone = traits.List xAxis = traits.Enum(values="masterList") yAxis = traits.Enum(values="masterList") series = traits.Enum(values="masterListWithNone") traits_view=traitsui.View(traitsui.VGroup(traitsui.Item("xAxis",label="x axis"),traitsui.Item("yAxis",label="y axis"), traitsui.Item("series",label="series"),show_border=True, label="axes selection")) def __init__(self, **traitsDict): """allows user to select which axes are useful for plotting in this log""" super(AxisSelector, self).__init__(**traitsDict) def _masterList_default(self): """gets the header row of log file which are interpreted as the column names that can be plotted.""" logger.info("updating master list of axis choices") logger.debug("comment file = %s" % self.logFile) logger.debug( "comment file = %s" % self.logFile) if not os.path.exists(self.logFile): return [] try: with open(self.logFile) as csvfile: headerReader = csv.reader(csvfile) headerRow=headerReader.next() return headerRow except IOError: return [] def _masterListWithNone_default(self): return ["None"]+self._masterList_default()
def get_axis_group(n, navigate, label=''): group_args = [ tui.Item('axis%i.name' % n), tui.Item('axis%i.size' % n, style='readonly'), tui.Item('axis%i.index_in_array' % n, style='readonly'), tui.Item('axis%i.low_index' % n, style='readonly'), tui.Item('axis%i.high_index' % n, style='readonly'), tui.Item('axis%i.units' % n), ] # The style of the index is chosen to be readonly because of # a bug in Traits 4.0.0 when using context with a Range traits # where the limits are defined by another traits_view if navigate: group_args.extend([ tui.Item('axis%i.index' % n, style='readonly'), tui.Item('axis%i.value' % n, style='readonly'), ]) group = tui.Group( tui.Group(*group_args, show_border=True,), tui.Group( tui.Item('axis%i.scale' % n), tui.Item('axis%i.offset' % n), label='Calibration', show_border=True,), label=label, show_border=True,) return group
def createOption(name, initialValue): """creates an option with a boolean attribute as the value, type should be the result of type(value)""" option = Option(name=name) if type(initialValue) is bool: option.add_trait("value", traits.Bool(initialValue)) elif type(initialValue) is int: option.add_trait("value", traits.Int(initialValue)) elif type(initialValue) is float: option.add_trait("value", traits.Float(initialValue)) elif type(initialValue) is str: option.add_trait("value", traits.File(initialValue)) # # need to modify the view, not sure how to make this more elegantly option.traits_view = traitsui.View( traitsui.HGroup( traitsui.Item("name", style="readonly", springy=True, show_label=False), traitsui.Item( "value", show_label=False, springy=True, editor=traitsui.FileEditor(dialog_style='save')))) else: logger.warning( "unrecognised option type ({}) in processor. Using traits.Any Editor and value" .format(type(initialValue))) option.add_trait("value", traits.Any(initialValue)) return option
class EntryBlock(traits.HasTraits): fieldName = traits.String( "fieldName", desc= "describes what the information to be entered in the text block is referring to" ) textBlock = traits.String() traits_view = traitsui.View( traitsui.VGroup(traitsui.Item("fieldName", show_label=False, style="readonly"), traitsui.Item("textBlock", show_label=False, style="custom"), show_border=True, label="information")) def __init__(self, **traitsDict): """user supplies arguments in init to supply class attributes defined above """ super(EntryBlock, self).__init__(**traitsDict) def clearTextBlock(self): self.textBlock = ""
class _H5Trees(api.HasTraits): h5_trees = api.Instance(Hdf5FilesNode) node = api.Any() path = api.Str() traits_view = ui.View( ui.Group( ui.Item( 'h5_trees', editor=_hdf5_tree_editor(selected='node'), resizable=True, ), ui.Item('path', label='Selected node'), orientation='vertical', ), title='Multiple HDF5 file Tree Example', buttons=['OK', 'Cancel'], resizable=True, width=0.3, height=0.3, ) def _node_changed(self): self.path = self.node.path print(self.node.path)
class SpectrumRangeSelector(SpanSelectorInSpectrum): on_close = t.List() view = tu.View( tu.Item('ss_left_value', label='Left', style='readonly'), tu.Item('ss_right_value', label='Right', style='readonly'), handler=SpectrumRangeSelectorHandler, buttons=[OKButton, OurApplyButton, CancelButton],)
def interactive_range_selector(obj, **kwargs): view = tu.View( tu.Item('ss_left_value', label='Left', style='readonly'), tu.Item('ss_right_value', label='Right', style='readonly'), handler=Signal1DRangeSelectorHandler, buttons=[OKButton, OurApplyButton, CancelButton], ) return obj, {"view": view}
def spikes_removal_traitsui(obj, **kwargs): thisOKButton = tu.Action(name="OK", action="OK", tooltip="Close the spikes removal tool") thisApplyButton = tu.Action(name="Remove spike", action="apply", tooltip="Remove the current spike by " "interpolating\n" "with the specified settings (and find\n" "the next spike automatically)") thisFindButton = tu.Action( name="Find next", action="find", tooltip="Find the next (in terms of navigation\n" "dimensions) spike in the data.") thisPreviousButton = tu.Action(name="Find previous", action="back", tooltip="Find the previous (in terms of " "navigation\n" "dimensions) spike in the data.") view = tu.View( tu.Group( tu.Group( tu.Item( 'click_to_show_instructions', show_label=False, ), tu.Item('show_derivative_histogram', show_label=False, tooltip="To determine the appropriate threshold,\n" "plot the derivative magnitude histogram, \n" "and look for outliers at high magnitudes \n" "(which represent sudden spikes in the data)"), 'threshold', show_border=True, ), tu.Group('add_noise', 'interpolator_kind', 'default_spike_width', tu.Group('spline_order', enabled_when='interpolator_kind == "Spline"'), show_border=True, label='Advanced settings'), ), buttons=[ thisOKButton, thisPreviousButton, thisFindButton, thisApplyButton, ], handler=SpikesRemovalHandler, title='Spikes removal tool', resizable=False, ) return obj, {"view": view}
class DishScene(TracerScene): """ Extends TracerScene with the variables required for this example and adds handling of simulation-specific details, like colouring the dish elements and setting proper resolution. """ refl = t_api.Float(1., label='Edge reflections') concent = t_api.Float(450, label='Concentration') disp_num_rays = t_api.Int(10) def __init__(self): dish, source = self.create_dish_source() TracerScene.__init__(self, dish, source) self.set_background((0., 0.5, 1.)) def create_dish_source(self): """ Creates the two basic elements of this simulation: the parabolic dish, and the pillbox-sunshape ray bundle. Uses the variables set by TraitsUI. """ dish, f, W, H = standard_minidish(1., self.concent, self.refl, 1., 1.) # Add GUI annotations to the dish assembly: for surf in dish.get_homogenizer().get_surfaces(): surf.colour = (1., 0., 0.) dish.get_main_reflector().colour = (0., 0., 1.) source = solar_disk_bundle(self.disp_num_rays, N.c_[[0., 0., f + H + 0.5]], N.r_[0., 0., -1.], 0.5, 0.00465) source.set_energy( N.ones(self.disp_num_rays) * 1000. / self.disp_num_rays) return dish, source @t_api.on_trait_change('refl, concent') def recreate_dish(self): """ Makes sure that the scene is redrawn upon dish design changes. """ dish, source = self.create_dish_source() self.set_assembly(dish) self.set_source(source) # Parameters of the form that is shown to the user: view = tui.View( tui.Item('_scene', editor=SceneEditor(scene_class=MayaviScene), height=500, width=500, show_label=False), tui.HGroup( '-', tui.Item('concent', editor=tui.TextEditor(evaluate=float, auto_set=False)), tui.Item('refl', editor=tui.TextEditor(evaluate=float, auto_set=False))))
def make_plugin_view(model_name, model_nodes, selection_view, model_view): node_label = '=' + model_name container_nodes = [ _traitsui.TreeNode( node_for=[CalcContainer], label=node_label, children='', auto_open=True, menu=[], ), _traitsui.TreeNode( node_for=[CalcContainer], label=node_label, children='calculations', auto_open=True, menu=[], ), ] plugin_tree = _traitsui.TreeEditor( nodes=container_nodes + model_nodes, # refresh='controller.update_tree', selected='controller.selected_object', editable=False, hide_root=True, ) plugin_view = _traitsui.View( _traitsui.Group( # Left side tree _traitsui.Item('controller.model', editor=plugin_tree, show_label=False), # Right side _traitsui.Group( # Upper right side data set selection panel selection_view, # Lower right side calc settings panel _traitsui.Group( _traitsui.Item( 'controller.edit_node', editor=_traitsui.InstanceEditor(view=model_view), style='custom', show_label=False), show_border=True, ), orientation='vertical', ), _traitsui.Spring(width=10), orientation='horizontal', ), resizable=True, buttons=['OK'], ) return plugin_view
class MultiMeshMorpher(ta.HasTraits): visible = ta.Enum(values='_names') morph_target = ta.Enum(values='_names') morph_alpha = ta.Range(0.0, 1.0, 0.0) show_edges = ta.Bool(False) _names = ta.List() def __init__(self, list_verts, tris, names=None, fig=None, **kw): super(MultiMeshMorpher, self).__init__(**kw) self._list_verts = list_verts self._tris = tris if fig is None: self._fig = mlab.figure(bgcolor=(1, 1, 1)) else: self._fig = fig if names is None: names = map(str, range(len(list_verts))) self._names = list(names) self._verts_by_name = dict(zip(self._names, list_verts)) self._actor, self._pd = mesh_as_vtk_actor(list_verts[0], tris, return_polydata=True) self._actor.property.set( ambient=0.0, specular=0.15, specular_power=128., diffuse=0.8, ) self._fig.scene.add_actor(self._actor) self.visible = self._names[0] if len(self._names) > 1: self.morph_target = self._names[1] @ta.on_trait_change('visible, show_edges, morph_target, morph_alpha') def _update(self): self._actor.property.edge_visibility = self.show_edges v1 = self._verts_by_name[self.visible] if self.morph_alpha > 0: v2 = self._verts_by_name[self.morph_target] self._pd.points = v1 * (1 - self.morph_alpha) + v2 * self.morph_alpha else: self._pd.points = v1 self._fig.scene.render() view = tu.View( tu.Group( tu.Item('visible'), tu.Item('morph_target'), tu.Item('morph_alpha'), tu.Item('show_edges', name='Wireframe'), label="Viewer"), title="MultiMeshMorpher" )
class Option(traits.HasTraits): name = traits.String( desc="key from options dictionary. describes the option") value = traits.Any() traits_view = traitsui.View( traitsui.HGroup( traitsui.Item("name", style="readonly", springy=True, show_label=False), traitsui.Item("value", show_label=False, springy=True)))
class CameraImage(traits.HasTraits): #Traits view definitions: traits_view = traitsui.View(traitsui.Group( traitsui.HGroup(traitsui.Item('pixelsX', label="Pixels X"), traitsui.Item('pixelsY', label="Pixels Y"))), buttons=["OK", "Cancel"]) pixelsX = traits.CInt(768) pixelsY = traits.CInt(512) xs = traits.Array ys = traits.Array zs = traits.Array minZ = traits.Float maxZ = traits.Float scale = traits.Float(1.) offset = traits.Float(0.) ODCorrectionBool = traits.Bool( False, desc= "if true will correct the image to account for the maximum OD parameter" ) ODSaturationValue = traits.Float( 3.0, desc="the value of the saturated optical density") model_changed = traits.Event def __init__(self, *args, **kwargs): super(CameraImage, self).__init__(*args, **kwargs) def _xs_default(self): return scipy.linspace(0.0, self.pixelsX - 1, self.pixelsX) def _ys_default(self): return scipy.linspace(0.0, self.pixelsY - 1, self.pixelsY) def _zs_default(self): #return scipy.zeros((self.pixelsY, self.pixelsX)) return scipy.random.random_sample((self.pixelsY, self.pixelsX)) def _scale_changed(self): """update zs data when scale or offset changed """ logger.info("model scale changed") #self.getImageData(self.imageFile) self.zs = scipy.random.random_sample((self.pixelsY, self.pixelsX)) self.model_changed = True def _offset_changed(self): """update zs data when scale or offset changed """
def context_variables_view(model): """ Instantiate a Traits UI View for a ContextVariableList. """ context_menu = menu.Menu( menu.ActionGroup( menu.Action(name='Execute for Selection', action='handler._on_execute(selection)'), menu.Action(name='Execute for All', action='handler._on_execute([])'), ), menu.ActionGroup( menu.Action(name='Delete', action='handler._on_delete(selection)'), ), menu.ActionGroup( menu.Action(name='Interact', action='handler._on_interact(selection)'), ), ) view = tui.View( tui.Item( 'search_term', show_label = False, editor = tui.SearchEditor( text = "Search for variables" ), ), tui.Item( 'search_results', id = 'search_results', show_label = False, editor = tui.TableEditor( columns = [ ObjectColumn(name='name', width=75), ContextVariableColumn(name='value', width=75), EditColumn(name='value', width=25) ], selected = 'table_selection', edit_on_first_click = False, auto_add = True, configurable = False, menu = context_menu, row_factory = context_variable_factory, sortable = False, sort_model = True, show_column_labels = False, selection_bg_color = 'light blue', selection_color = 'black', selection_mode = 'rows', label_bg_color = WindowColor, cell_bg_color = 0xFFFFFF, auto_size = False, ), ), id = 'context_variables_view', resizable = True, handler = CVLHandler(model=model), ) return view
class Signal1DCalibration(SpanSelectorInSignal1D): left_value = t.Float(label='New left value') right_value = t.Float(label='New right value') offset = t.Float() scale = t.Float() units = t.Unicode() view = tu.View(tu.Group( 'left_value', 'right_value', tu.Item('ss_left_value', label='Left', style='readonly'), tu.Item('ss_right_value', label='Right', style='readonly'), tu.Item(name='offset', style='readonly'), tu.Item(name='scale', style='readonly'), 'units', ), handler=CalibrationHandler, buttons=[OKButton, OurApplyButton, CancelButton], kind='live', title='Calibration parameters') def __init__(self, signal): super(Signal1DCalibration, self).__init__(signal) if signal.axes_manager.signal_dimension != 1: raise SignalDimensionError(signal.axes_manager.signal_dimension, 1) self.units = self.axis.units self.last_calibration_stored = True def _left_value_changed(self, old, new): if self.span_selector is not None and \ self.span_selector.range is None: messages.information('Please select a range in the spectrum figure' 'by dragging the mouse over it') return else: self._update_calibration() def _right_value_changed(self, old, new): if self.span_selector.range is None: messages.information('Please select a range in the spectrum figure' 'by dragging the mouse over it') return else: self._update_calibration() def _update_calibration(self, *args, **kwargs): if self.left_value == self.right_value: return lc = self.axis.value2index(self.ss_left_value) rc = self.axis.value2index(self.ss_right_value) self.offset, self.scale = self.axis.calibrate( (self.left_value, self.right_value), (lc, rc), modify_calibration=False)
def _update_fired(self): self.disc_list = np.exp(-self.rate * self.time_list) v = trui.View(trui.Group(trui.Item(name='name'), trui.Item(name='rate'), trui.Item(name='time_list', label='Insert Time List Here'), trui.Item(name='update', show_label=False), trui.Item(name='disc_list', label='Press Update for Factors'), show_border=True, label='Calculate Discount Factors'), buttons=[trui.OKButton, trui.CancelButton], resizable=True)
class ErrorMessage(_traits.HasTraits): err_msg = _traits.Str() msg_val = _traits.Str() traits_view = _traitsui.View( _traitsui.Item('err_msg', show_label=False, style='readonly'), _traitsui.Item('err_val', show_label=False, style='custom'), title='Warning', height=100, width=400, resizable=True, buttons=[_traitsui.OKButton], )
class PlotOptions(tr.HasTraits): columns_headers_list = tr.List([]) x_axis = tr.Enum(values='columns_headers_list') y_axis = tr.Enum(values='columns_headers_list') x_axis_multiplier = tr.Enum(1, -1) y_axis_multiplier = tr.Enum(-1, 1) plot = tr.Button view = ui.View( ui.HGroup(ui.Item('x_axis'), ui.Item('x_axis_multiplier')), ui.HGroup(ui.Item('y_axis'), ui.Item('y_axis_multiplier')), ui.Item('plot', show_label=False) )
def get_data_axis_view(navigate, label): group_args = [ tui.Item(name='name'), tui.Item(name='size', style='readonly'), tui.Item(name='index_in_array', style='readonly'), tui.Item(name='units'), ] if navigate: group_args.extend([ tui.Item(name='index'), tui.Item(name='value', style='readonly'), ]) data_axis_view = tui.View( tui.Group( tui.Group(*group_args, show_border=True,), tui.Group( tui.Item(name='scale'), tui.Item(name='offset'), label='Calibration', show_border=True,), # label="Data Axis properties", show_border=True,), title=label,) return data_axis_view
def calibration2d_traitsui(obj, **kwargs): view = tu.View( tu.Group( "new_length", tu.Item("length", label="Current length", style="readonly"), tu.Item(name="scale", style="readonly"), "units", ), handler=Calibration2DHandler, buttons=[OurApplyButton, CancelButton], kind="live", title="Calibration parameters", ) return obj, {"view": view}
def fit_component_traitsui(obj, **kwargs): fit_component_view = tu.View( tu.Item( 'only_current', show_label=True, ), tu.Item('iterpath', show_label=True, enabled_when='only_current==False'), buttons=[OurFitButton, OurCloseButton], title='Fit single component', handler=ComponentFitHandler, ) return obj, {"view": fit_component_view}
class cash_flow_series(trapi.HasTraits): name = trapi.Str short_rate = trapi.Range(0.0, 0.5, 0.05) time_list = trapi.Array(dtype=np.float, shape=(1, 6)) cash_flows = trapi.Array(dtype=np.float, shape=(1, 6)) disc_values = trapi.Array(dtype=np.float, shape=(1, 6)) present_values = trapi.Array(dtype=np.float, shape=(1, 6)) net_present_value = trapi.Float update = trapi.Button def _update_fired(self): self.disc_values = np.exp(-self.short_rate * self.time_list) self.present_values = self.disc_values * self.cash_flows self.net_present_value = np.sum(self.present_values) v = trui.View(trui.Group(trui.Item(name='name'), trui.Item(name='short_rate'), trui.Item(name='time_list', label='Time List'), trui.Item(name='cash_flows', label='Cash Flows'), trui.Item('update', show_label=False), trui.Item(name='disc_values', label='Discount Factors'), trui.Item(name='present_values', label='Present Values'), trui.Item(name='net_present_value', label='Net Present Value'), show_border=True, label='Calculate Present Values'), buttons=[trui.OKButton, trui.CancelButton], resizable=True)
class ViewHandler(ui.Handler): # You can initialize this by obtaining it from the methods below and, self.info = info info = tr.Instance(ui.UIInfo) exit_view = ui.View(ui.VGroup( ui.Label('Do you really wish to end ' 'the session? Any unsaved data ' 'will be lost.'), ui.HGroup(ui.Item('ok', show_label=False, springy=True), ui.Item('cancel', show_label=False, springy=True))), title='Exit dialog', kind='live') def menu_utilities_csv_joiner(self): csv_joiner = CSVJoiner() # kind='modal' pauses the background traits window until this window is closed csv_joiner.configure_traits() def menu_about_tool(self): about_tool = AboutTool() about_tool.configure_traits() def get_outfile(self, folder_name, file_name): '''Returns a file in the specified folder using the home directory as root. ''' HOME_DIR = os.path.expanduser("~") out_dir = os.path.join(HOME_DIR, folder_name) if not os.path.exists(out_dir): os.makedirs(out_dir) outfile = os.path.join(out_dir, file_name) return outfile def menu_save(self, info): file_name = self.get_outfile(folder_name='.hcft', file_name='') file_ = save_file(file_name=file_name) if file_: pickle.dump(info.object.root, open(file_, 'wb'), 1) def menu_open(self, info): file_name = self.get_outfile(folder_name='.hcft', file_name='') file_ = open_file(file_name=file_name) if file_: info.object.root = pickle.load(open(file_, 'rb')) def menu_exit(self, info): if info.initialized: info.ui.dispose()