              trainer.train_one_step(viewer, timelapse)
  
              if viewer is not None and not save_iteration:
                  # Spammy but required by GUI to know to update window
                  print("\n")
                  logger.info("[Preview Updated]")
  
              if self._stop:
                  logger.debug("Stop received. Terminating")
                  break
 
</s> remove                 if self._preview.should_quit():
 </s> add                 if self._preview.should_quit: </s> remove                 # GUI Preview trigger update monitor
                self._process_gui_triggers()

 </s> add  </s> remove 
        logger.debug("Preview window keypress '%s' received", key)
        if key == "r":
            print("\n")  # Let log print on different line from loss output
            logger.info("Refresh preview requested...")

        with self._lock:
            if key == "f":
                self._toggle_size()
            else:
                self._triggers[self._callbacks[key]] = True

    def _on_resize(self,
                   event: backend_bases.ResizeEvent) -> None:  # noqa # pylint:disable=unused-argument
        """ If the display is set to `actual size` then the image needs to be resized on any window
        resize event. """
        for fig, size in self._images.values():
            fig.set_size_inches(size)

    def _on_close(self,
                   event: backend_bases.CloseEvent) -> None:  # noqa # pylint:disable=unused-argument
        """ Force an update when the figure has been closed to relaunch it. """
        logger.debug("Preview close detected")
        with self._lock:
            self._needs_update = True
 </s> add         logger.debug("Sending shutdown to preview viewer")
        self._triggers["shutdown"].set() </s> remove         Parameters
        ----------
        name: str
            The name to display in the window header and for window identification
        shape: tuple
            The (`rows`, `columns`, `channels`) of the image to be displayed
 </s> add         Returns
        -------
        :class:`lib.multithreading.FSThread` or ``None``
            The thread that holds the preview viewer if preview is selected otherwise ``None`` </s> remove         Parameters
        ----------
        event:
            The key press received
        """
        key = event.key.lower()
        if key not in self._callbacks:
 </s> add     def shutdown(self) -> None:
        """ Send a signal to shutdown the preview window. """
        if not self._active:
                print("")
              trainer.train_one_step(viewer, timelapse)
  
              if viewer is not None and not save_iteration:
                  # Spammy but required by GUI to know to update window
                print("")
                  logger.info("[Preview Updated]")
  
              if self._stop:
                  logger.debug("Stop received. Terminating")
                  break
keep keep keep keep replace keep keep keep keep keep
 Training - Use custom preview pop-out 
scripts/train.py