def __init__(self, name): """ :param name: Name of the object given by the user. :return: FlatCAMObj """ QtCore.QObject.__init__(self) # View self.ui = None self.options = LoudDict(name=name) self.options.set_change_callback(self.on_options_change) self.form_fields = {} self.axes = None # Matplotlib axes self.kind = None # Override with proper name self.muted_ui = False
class FlatCAMObj(QtCore.QObject): """ Base type of objects handled in FlatCAM. These become interactive in the GUI, can be plotted, and their options can be modified by the user in their respective forms. """ # Instance of the application to which these are related. # The app should set this value. app = None def __init__(self, name): """ :param name: Name of the object given by the user. :return: FlatCAMObj """ QtCore.QObject.__init__(self) # View self.ui = None self.options = LoudDict(name=name) self.options.set_change_callback(self.on_options_change) self.form_fields = {} self.axes = None # Matplotlib axes self.kind = None # Override with proper name self.muted_ui = False # assert isinstance(self.ui, ObjectUI) # self.ui.name_entry.returnPressed.connect(self.on_name_activate) # self.ui.offset_button.clicked.connect(self.on_offset_button_click) # self.ui.scale_button.clicked.connect(self.on_scale_button_click) def on_options_change(self, key): self.emit(QtCore.SIGNAL("optionChanged"), key) def set_ui(self, ui): self.ui = ui self.form_fields = {"name": self.ui.name_entry} assert isinstance(self.ui, ObjectUI) self.ui.name_entry.returnPressed.connect(self.on_name_activate) self.ui.offset_button.clicked.connect(self.on_offset_button_click) self.ui.scale_button.clicked.connect(self.on_scale_button_click) def __str__(self): return "<FlatCAMObj({:12s}): {:20s}>".format(self.kind, self.options["name"]) def on_name_activate(self): old_name = copy(self.options["name"]) new_name = self.ui.name_entry.get_value() self.options["name"] = self.ui.name_entry.get_value() self.app.info("Name changed from %s to %s" % (old_name, new_name)) def on_offset_button_click(self): self.app.report_usage("obj_on_offset_button") self.read_form() vect = self.ui.offsetvector_entry.get_value() self.offset(vect) self.plot() def on_scale_button_click(self): self.app.report_usage("obj_on_scale_button") self.read_form() factor = self.ui.scale_entry.get_value() self.scale(factor) self.plot() def setup_axes(self, figure): """ 1) Creates axes if they don't exist. 2) Clears axes. 3) Attaches them to figure if not part of the figure. 4) Sets transparent background. 5) Sets 1:1 scale aspect ratio. :param figure: A Matplotlib.Figure on which to add/configure axes. :type figure: matplotlib.figure.Figure :return: None :rtype: None """ if self.axes is None: FlatCAMApp.App.log.debug("setup_axes(): New axes") self.axes = figure.add_axes([0.05, 0.05, 0.9, 0.9], label=self.options["name"]) elif self.axes not in figure.axes: FlatCAMApp.App.log.debug( "setup_axes(): Clearing and attaching axes") self.axes.cla() figure.add_axes(self.axes) else: FlatCAMApp.App.log.debug("setup_axes(): Clearing Axes") self.axes.cla() # Remove all decoration. The app's axes will have # the ticks and grid. self.axes.set_frame_on(False) # No frame self.axes.set_xticks([]) # No tick self.axes.set_yticks([]) # No ticks self.axes.patch.set_visible(False) # No background self.axes.set_aspect(1) def to_form(self): """ Copies options to the UI form. :return: None """ for option in self.options: self.set_form_item(option) def read_form(self): """ Reads form into ``self.options``. :return: None :rtype: None """ FlatCAMApp.App.log.debug( str(inspect.stack()[1][3]) + "--> FlatCAMObj.read_form()") for option in self.options: self.read_form_item(option) def build_ui(self): """ Sets up the UI/form for this object. Show the UI in the App. :return: None :rtype: None """ self.muted_ui = True FlatCAMApp.App.log.debug( str(inspect.stack()[1][3]) + "--> FlatCAMObj.build_ui()") # Remove anything else in the box # box_children = self.app.ui.notebook.selected_contents.get_children() # for child in box_children: # self.app.ui.notebook.selected_contents.remove(child) # while self.app.ui.selected_layout.count(): # self.app.ui.selected_layout.takeAt(0) # Put in the UI # box_selected.pack_start(sw, True, True, 0) # self.app.ui.notebook.selected_contents.add(self.ui) # self.app.ui.selected_layout.addWidget(self.ui) try: self.app.ui.selected_scroll_area.takeWidget() except: self.app.log.debug("Nothing to remove") self.app.ui.selected_scroll_area.setWidget(self.ui) self.to_form() self.muted_ui = False def set_form_item(self, option): """ Copies the specified option to the UI form. :param option: Name of the option (Key in ``self.options``). :type option: str :return: None """ try: self.form_fields[option].set_value(self.options[option]) except KeyError: self.app.log.warn( "Tried to set an option or field that does not exist: %s" % option) def read_form_item(self, option): """ Reads the specified option from the UI form into ``self.options``. :param option: Name of the option. :type option: str :return: None """ try: self.options[option] = self.form_fields[option].get_value() except KeyError: self.app.log.warning("Failed to read option from field: %s" % option) def plot(self): """ Plot this object (Extend this method to implement the actual plotting). Axes get created, appended to canvas and cleared before plotting. Call this in descendants before doing the plotting. :return: Whether to continue plotting or not depending on the "plot" option. :rtype: bool """ FlatCAMApp.App.log.debug( str(inspect.stack()[1][3]) + " --> FlatCAMObj.plot()") # Axes must exist and be attached to canvas. if self.axes is None or self.axes not in self.app.plotcanvas.figure.axes: self.axes = self.app.plotcanvas.new_axes(self.options['name']) if not self.options["plot"]: self.axes.cla() self.app.plotcanvas.auto_adjust_axes() return False # Clear axes or we will plot on top of them. self.axes.cla() # TODO: Thread safe? return True def serialize(self): """ Returns a representation of the object as a dictionary so it can be later exported as JSON. Override this method. :return: Dictionary representing the object :rtype: dict """ return def deserialize(self, obj_dict): """ Re-builds an object from its serialized version. :param obj_dict: Dictionary representing a FlatCAMObj :type obj_dict: dict :return: None """ return
class FlatCAMObj(QtCore.QObject): """ Base type of objects handled in FlatCAM. These become interactive in the GUI, can be plotted, and their options can be modified by the user in their respective forms. """ # Instance of the application to which these are related. # The app should set this value. app = None def __init__(self, name): """ :param name: Name of the object given by the user. :return: FlatCAMObj """ QtCore.QObject.__init__(self) # View self.ui = None self.options = LoudDict(name=name) self.options.set_change_callback(self.on_options_change) self.form_fields = {} self.axes = None # Matplotlib axes self.kind = None # Override with proper name self.muted_ui = False # assert isinstance(self.ui, ObjectUI) # self.ui.name_entry.returnPressed.connect(self.on_name_activate) # self.ui.offset_button.clicked.connect(self.on_offset_button_click) # self.ui.scale_button.clicked.connect(self.on_scale_button_click) def on_options_change(self, key): self.emit(QtCore.SIGNAL("optionChanged"), key) def set_ui(self, ui): self.ui = ui self.form_fields = {"name": self.ui.name_entry} assert isinstance(self.ui, ObjectUI) self.ui.name_entry.returnPressed.connect(self.on_name_activate) self.ui.offset_button.clicked.connect(self.on_offset_button_click) self.ui.scale_button.clicked.connect(self.on_scale_button_click) def __str__(self): return "<FlatCAMObj({:12s}): {:20s}>".format(self.kind, self.options["name"]) def on_name_activate(self): old_name = copy(self.options["name"]) new_name = self.ui.name_entry.get_value() self.options["name"] = self.ui.name_entry.get_value() self.app.info("Name changed from %s to %s" % (old_name, new_name)) def on_offset_button_click(self): self.app.report_usage("obj_on_offset_button") self.read_form() vect = self.ui.offsetvector_entry.get_value() self.offset(vect) self.plot() def on_scale_button_click(self): self.app.report_usage("obj_on_scale_button") self.read_form() factor = self.ui.scale_entry.get_value() self.scale(factor) self.plot() def setup_axes(self, figure): """ 1) Creates axes if they don't exist. 2) Clears axes. 3) Attaches them to figure if not part of the figure. 4) Sets transparent background. 5) Sets 1:1 scale aspect ratio. :param figure: A Matplotlib.Figure on which to add/configure axes. :type figure: matplotlib.figure.Figure :return: None :rtype: None """ if self.axes is None: FlatCAMApp.App.log.debug("setup_axes(): New axes") self.axes = figure.add_axes([0.05, 0.05, 0.9, 0.9], label=self.options["name"]) elif self.axes not in figure.axes: FlatCAMApp.App.log.debug("setup_axes(): Clearing and attaching axes") self.axes.cla() figure.add_axes(self.axes) else: FlatCAMApp.App.log.debug("setup_axes(): Clearing Axes") self.axes.cla() # Remove all decoration. The app's axes will have # the ticks and grid. self.axes.set_frame_on(False) # No frame self.axes.set_xticks([]) # No tick self.axes.set_yticks([]) # No ticks self.axes.patch.set_visible(False) # No background self.axes.set_aspect(1) def to_form(self): """ Copies options to the UI form. :return: None """ for option in self.options: self.set_form_item(option) def read_form(self): """ Reads form into ``self.options``. :return: None :rtype: None """ FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> FlatCAMObj.read_form()") for option in self.options: self.read_form_item(option) def build_ui(self): """ Sets up the UI/form for this object. Show the UI in the App. :return: None :rtype: None """ self.muted_ui = True FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + "--> FlatCAMObj.build_ui()") # Remove anything else in the box # box_children = self.app.ui.notebook.selected_contents.get_children() # for child in box_children: # self.app.ui.notebook.selected_contents.remove(child) # while self.app.ui.selected_layout.count(): # self.app.ui.selected_layout.takeAt(0) # Put in the UI # box_selected.pack_start(sw, True, True, 0) # self.app.ui.notebook.selected_contents.add(self.ui) # self.app.ui.selected_layout.addWidget(self.ui) try: self.app.ui.selected_scroll_area.takeWidget() except: self.app.log.debug("Nothing to remove") self.app.ui.selected_scroll_area.setWidget(self.ui) self.to_form() self.muted_ui = False def set_form_item(self, option): """ Copies the specified option to the UI form. :param option: Name of the option (Key in ``self.options``). :type option: str :return: None """ try: self.form_fields[option].set_value(self.options[option]) except KeyError: self.app.log.warn("Tried to set an option or field that does not exist: %s" % option) def read_form_item(self, option): """ Reads the specified option from the UI form into ``self.options``. :param option: Name of the option. :type option: str :return: None """ try: self.options[option] = self.form_fields[option].get_value() except KeyError: self.app.log.warning("Failed to read option from field: %s" % option) def plot(self): """ Plot this object (Extend this method to implement the actual plotting). Axes get created, appended to canvas and cleared before plotting. Call this in descendants before doing the plotting. :return: Whether to continue plotting or not depending on the "plot" option. :rtype: bool """ FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + " --> FlatCAMObj.plot()") # Axes must exist and be attached to canvas. if self.axes is None or self.axes not in self.app.plotcanvas.figure.axes: self.axes = self.app.plotcanvas.new_axes(self.options['name']) if not self.options["plot"]: self.axes.cla() self.app.plotcanvas.auto_adjust_axes() return False # Clear axes or we will plot on top of them. self.axes.cla() # TODO: Thread safe? return True def serialize(self): """ Returns a representation of the object as a dictionary so it can be later exported as JSON. Override this method. :return: Dictionary representing the object :rtype: dict """ return def deserialize(self, obj_dict): """ Re-builds an object from its serialized version. :param obj_dict: Dictionary representing a FlatCAMObj :type obj_dict: dict :return: None """ return