          self._image = image
  
          self._drag_data: List[float] = [0., 0.]
          self._set_mouse_bindings()
          self._set_key_bindings()
          logger.debug("Initialized %s", self.__class__.__name__,)
  
      def _on_bound_zoom(self, event: tk.Event) -> None:
          """ Action to perform on a valid zoom key press or mouse wheel action
  
 
</s> remove         for preview in self.subnotebook.children.values():
            preview.save_preview(location)


class PreviewTrainCanvas(ttk.Frame):  # pylint: disable=too-many-ancestors
    """ Canvas to hold a training preview image

    Parameters
    ----------
    parent: :class:`tkinter.ttk.Notebook`
        The notebook that the training image canvas belongs to
    previewname: str
        The name of the preview image displayed in the canvas
    """
    def __init__(self, parent: ttk.Notebook, previewname: str) -> None:
        logger.debug("Initializing %s: (previewname: '%s')", self.__class__.__name__, previewname)
        ttk.Frame.__init__(self, parent)

        self.name = previewname
        get_images().resize_image(self.name, None)
        self.previewimage = get_images().previewtrain[self.name][1]

        self.canvas = tk.Canvas(self, bd=0, highlightthickness=0)
        self.canvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.imgcanvas = self.canvas.create_image(0,
                                                  0,
                                                  image=self.previewimage,
                                                  anchor=tk.NW)
        self.bind("<Configure>", self.resize)
        logger.debug("Initialized %s:", self.__class__.__name__)

    def resize(self, event: tk.Event) -> None:
        """  Resize the image to fit the frame, maintaining aspect ratio
 </s> add  </s> remove         Parameters
        ----------
        event: :class:`tkinter.Event`
            The resize event object
        """
        logger.trace("Resizing preview image")  # type:ignore
        framesize: Optional[Tuple[int, int]] = (event.width, event.height)
        # Sometimes image is resized before frame is drawn
        framesize = None if framesize == (1, 1) else framesize
        get_images().resize_image(self.name, framesize)
        self.reload()

    def reload(self) -> None:
        """ Reload the preview image """
        logger.trace("Reloading preview image")  # type:ignore
        self.previewimage = get_images().previewtrain[self.name][1]
        self.canvas.itemconfig(self.imgcanvas, image=self.previewimage)

    def save_preview(self, location: str) -> None:
        """ Save the figure to file.

        Parameters
        ----------
        location: str
            The full path to the location to save the preview image
        """
        filename = self.name
        now = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = os.path.join(location, f"{filename}_{now}.png")
        cast("Image.Image", get_images().previewtrain[self.name][0]).save(filename)
        logger.debug("Saved preview to %s", filename)
        print(f"Saved preview to {filename}")
 </s> add         self._display.save(location) </s> remove             Tuple containing either the key press event (Ctrl+s shortcut) or the tk variable
            arguments (save button press)
 </s> add             Tuple containing either the key press event (Ctrl+s shortcut), the tk variable
            arguments (standalone save button press) or the folder location (GUI save button press) </s> remove         if not self._save_var.get() and not isinstance(args[0], tk.Event):
 </s> add         if self._is_standalone and not self._save_var.get() and not isinstance(args[0], tk.Event): </s> remove     @classmethod
    def _output_helptext(cls) -> None:
 </s> add     @property
    def master_frame(self) -> tk.Frame:
        """ :class:`tkinter.Frame`: The master frame that holds the preview window """
        return self._master_frame

    def pack(self, *args, **kwargs):
        """ Redirect calls to pack the widget to pack the actual :attr:`_master_frame`.

        Takes standard :class:`tkinter.Frame` pack arguments
        """
        logger.debug("Packing master frame: (args: %s, kwargs: %s)", args, kwargs)
        self._master_frame.pack(*args, **kwargs)

    def save(self, location: str) -> None:
        """ Save action to be performed when save button pressed from the GUI.

        location: str
            Full path to the folder to save the preview image to
        """
        self._image.save_preview(location)

    def remove_option_controls(self) -> None:
        """ Remove the taskbar options controls when the preview is disabled in the GUI """
        self._taskbar.destroy_widgets()

    def _output_helptext(self) -> None:
        self._set_key_bindings(is_standalone)
          self._image = image
  
          self._drag_data: List[float] = [0., 0.]
          self._set_mouse_bindings()
        self._set_key_bindings(is_standalone)
          logger.debug("Initialized %s", self.__class__.__name__,)
  
      def _on_bound_zoom(self, event: tk.Event) -> None:
          """ Action to perform on a valid zoom key press or mouse wheel action
  
keep keep keep keep replace keep keep keep keep keep
 GUI - Preview updates
  - Training preview. Embed preview pop-out window
  - Bugfix - convert/extract previews 
lib/training/preview_tk.py