          args: tuple
              Tuple containing either the key press event (Ctrl+s shortcut) or the tk variable
              arguments (save button press)
          """
          if not self._save_var.get() and not isinstance(args[0], tk.Event):
              return
  
          root_path = os.path.join(os.path.realpath(os.path.dirname(sys.argv[0])))
          now = datetime.now().strftime("%Y-%m-%d_%H.%M.%S")
          filename = os.path.join(root_path, f"preview_{now}.png")
 
</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         root_path = os.path.join(os.path.realpath(os.path.dirname(sys.argv[0])))
 </s> add         if self._is_standalone:
            root_path = os.path.join(os.path.realpath(os.path.dirname(sys.argv[0])))
        else:
            root_path = args[0]
 </s> remove         self._save_var.set(False)
 </s> add         if self._is_standalone:
            self._save_var.set(False) </s> remove     def previewoutput(self) -> Tuple[Image.Image, ImageTk.PhotoImage]:
        """ Tuple: First item in the tuple is the extract or convert preview image
        (:class:`PIL.Image`), the second item is the image in a format that tkinter can display
        (:class:`PIL.ImageTK.PhotoImage`).
 </s> add     def buffer(self) -> PreviewBuffer:
        """ :class:`~lib.training.PreviewBuffer` The preview buffer for the training preview
        image. """
        return self._buffer

    def load(self) -> bool:
        """ Load the latest training preview image(s) from disk and add to :attr:`buffer` """
        logger.trace("Loading Training preview images")  # type:ignore
        image_files = _get_previews(self._cache_path)
        filename = next((fname for fname in image_files
                         if os.path.basename(fname) == TRAININGPREVIEW), "")
        if not filename:
            logger.trace("No preview to display")  # type:ignore
            return False
        try:
            modified = os.path.getmtime(filename)
            if modified <= self._modified:
                logger.trace("preview '%s' not updated. Current timestamp: %s, "  # type:ignore
                             "existing timestamp: %s", filename, modified, self._modified)
                return False

            logger.debug("Loading preview: '%s'", filename)
            img = cv2.imread(filename, cv2.IMREAD_UNCHANGED)
            self._modified = modified
            self._buffer.add_image(os.path.basename(filename), img)
            self._error_count = 0
        except ValueError:
            # This is probably an error reading the file whilst it's being saved so ignore it
            # for now and only pick up if there have been multiple consecutive fails
            logger.warning("Unable to display preview: (image: '%s', attempt: %s)",
                           img, self._error_count)
            if self._error_count < 10:
                self._error_count += 1
            else:
                logger.error("Error reading the preview file for '%s'", filename)
            return False </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)
        if self._is_standalone and not self._save_var.get() and not isinstance(args[0], tk.Event):
          args: tuple
              Tuple containing either the key press event (Ctrl+s shortcut) or the tk variable
              arguments (save button press)
          """
        if self._is_standalone and not self._save_var.get() and not isinstance(args[0], tk.Event):
              return
  
          root_path = os.path.join(os.path.realpath(os.path.dirname(sys.argv[0])))
          now = datetime.now().strftime("%Y-%m-%d_%H.%M.%S")
          filename = os.path.join(root_path, f"preview_{now}.png")
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