      def launch_faceswap(self, command):
          ''' Launch the script inside a subprocess to keep the GUI active '''
          self.statustext.set('Executing: ' + command.title())
          try:
              self.parser.set_defaults(func=self.bad_args)
              arguments = self.parser.parse_args()
              arguments.func(arguments)
          except:
              self.statustext.set('Failed: ' + command.title())    
              raise
          self.statustext.set('Idle')
          exit()        
  
  class TKGui(object):
      ''' Main GUI Control '''
      def __init__ (self, subparser, subparsers, parser, command, description='default'):
      # Don't try to load the GUI if there is no display or there are problems importing tkinter
 
</s> remove     ''' Main GUI Control '''
    def __init__ (self, subparser, subparsers, parser, command, description='default'):
    # Don't try to load the GUI if there is no display or there are problems importing tkinter
 </s> add     """ Main GUI Control """

    def __init__(self, subparser, subparsers, command, description='default'):
        # Don't try to load the GUI if there is no display or there are
        # problems importing tkinter </s> remove         if not check_display(cmd) or not import_tkinter(cmd):
 </s> add         if not self.check_display(cmd) or not self.check_tkinter_available(cmd): </s> remove        
        self.parser = parser
 </s> add         self.arguments = None </s> remove # Users without tkinter distrubtion packages or without an X-Console will error out
# importing tkinter. Therefore run a check on these and only import if required 
tk = None
ttk = None
filedialog = None

def import_tkinter(command):
    ''' Perform checks when importing tkinter module to ensure that GUI will load '''
    global tk
    global ttk
    global filedialog
    try:
        import tkinter
        from tkinter import ttk
        from tkinter import filedialog
        tk = tkinter
    except ImportError:
        if 'gui' in command:
            print(  'It looks like TkInter isn''t installed for your OS, so the GUI has been '
                    'disabled. To enable the GUI please install the TkInter application.\n'
                    'You can try:\n'
                    '  Windows/macOS:      Install ActiveTcl Community Edition from '
                    'www.activestate.com\n'
                    '  Ubuntu/Mint/Debian: sudo apt install python3-tk\n'
                    '  Arch:               sudo pacman -S tk\n'
                    '  CentOS/Redhat:      sudo yum install tkinter\n'
                    '  Fedora:             sudo dnf install python3-tkinter\n')
        return False
    return True    

def check_display(command):
    # Check whether there is a display to output the GUI. If running on Windows
    # then assume not running in headless mode
    if not os.environ.get('DISPLAY', None) and os.name != 'nt':
        if 'gui' in command:
            print ('Could not detect a display. The GUI has been disabled')
        return False
    return True
 </s> add PATHSCRIPT = os.path.realpath(os.path.dirname(sys.argv[0])) </s> remove                 optlist.extend((opt, optval))
        sys.argv = optlist
        process = Thread(target=self.launch_faceswap, args=(self.command,))
        process.start()

    def launch_faceswap(self, command):
        ''' Launch the script inside a subprocess to keep the GUI active '''
        self.statustext.set('Executing: ' + command.title())
 </s> add                 self.args.extend((opt, optval))

    def execute_script(self):
        """ Execute the requested Faceswap Script """
        kwargs = {'stdout': PIPE,
                  'stderr': PIPE,
                  'bufsize': 1,
                  'universal_newlines': True}
        if os.name == 'nt':
            kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
        self.process = Popen(self.args, **kwargs)
        self.thread_stdout()
        self.thread_stderr()

    def read_stdout(self):
        """ Read stdout from the subprocess. If training, pass the loss
        values to Queue """
        while True:
            output = self.process.stdout.readline()
            if output == '' and self.process.poll() is not None:
                break
            if output:
                if self.command == 'train' and str.startswith(output, '['):
                    self.capture_loss(output)
                print(output.strip())
        returncode = self.process.poll()
        self.utils.runningtask = False
        self.utils.change_action_button()
        self.set_final_status(returncode)
        print('Process exited.')

    def read_stderr(self):
        """ Read stdout from the subprocess. If training, pass the loss
        values to Queue """
        while True:
            output = self.process.stderr.readline()
            if output == '' and self.process.poll() is not None:
                break
            print(output.strip(), file=sys.stderr)

    def thread_stdout(self):
        """ Put the subprocess stdout so that it can be read without
        blocking """
        thread = Thread(target=self.read_stdout)
        thread.daemon = True
        thread.start()

    def thread_stderr(self):
        """ Put the subprocess stderr so that it can be read without
        blocking """
        thread = Thread(target=self.read_stderr)
        thread.daemon = True
        thread.start()

    def capture_loss(self, string):
        """ Capture loss values from stdout """
        #TODO: Remove this hideous hacky fix. When the subprocess is terminated and
        # the loss dictionary is reset, 1 set of loss values ALWAYS slips through
        # and appends to the lossdict AFTER the subprocess has closed meaning that
        # checks on whether the dictionary is empty fail.
        # Therefore if the size of current loss dictionary is smaller than the
        # previous loss dictionary, assume that the process has been terminated
        # and reset it.
        # I have tried and failed to empty the subprocess stdout with:
        #   sys.exit() on the stdout/err threads (no effect)
        #   sys.stdout/stderr.flush (no effect)
        #   thread.join (locks the whole process up, because the stdout thread
        #       stubbonly refuses to release it's last line)

        currentlenloss = len(self.utils.lossdict)
        if self.lenloss > currentlenloss:
            self.utils.lossdict = dict()
            self.lenloss = 0
            return
        self.lenloss = currentlenloss

        loss = re.findall(r'([a-zA-Z_]+):.*?(\d+\.\d+)', string)

        if len(loss) < 2:
            return

        if not self.utils.lossdict:
            self.utils.lossdict.update((item[0], []) for item in loss)

        for item in loss:
            self.utils.lossdict[item[0]].append(float(item[1]))

    def terminate(self):
        """ Terminate the subprocess """
        if self.command == 'train':
            print('Sending Exit Signal', flush=True)
            try:
                now = time()
                if os.name == 'nt':
                    os.kill(self.process.pid, signal.CTRL_BREAK_EVENT)
                else:
                    self.process.send_signal(signal.SIGINT)
                while True:
                    timeelapsed = time() - now
                    if self.process.poll() is not None:
                        break
                    if timeelapsed > 30:
                        raise ValueError('Timeout reached sending Exit Signal')
                return
            except ValueError as err:
                print(err)
        print('Terminating Process...')
            self.process.terminate()
            self.process.wait(timeout=10)
            print('Terminated')
        except TimeoutExpired:
            print('Termination timed out. Killing Process...')
            self.process.kill()
            print('Killed')

    def set_final_status(self, returncode):
        """ Set the status bar output based on subprocess return code """
        if returncode == 0 or returncode == 3221225786:
            status = 'Ready'
        elif returncode == -15:
            status = 'Terminated - {}.py'.format(self.command)
        elif returncode == -9:
            status = 'Killed - {}.py'.format(self.command)
        elif returncode == -6:
            status = 'Aborted - {}.py'.format(self.command)
        else:
            status = 'Failed - {}.py. Return Code: {}'.format(self.command, returncode)
        self.utils.guitext['status'].set(status)

      def launch_faceswap(self, command):
          ''' Launch the script inside a subprocess to keep the GUI active '''
          self.statustext.set('Executing: ' + command.title())
          try:
            self.process.terminate()
            self.process.wait(timeout=10)
            print('Terminated')
        except TimeoutExpired:
            print('Termination timed out. Killing Process...')
            self.process.kill()
            print('Killed')

    def set_final_status(self, returncode):
        """ Set the status bar output based on subprocess return code """
        if returncode == 0 or returncode == 3221225786:
            status = 'Ready'
        elif returncode == -15:
            status = 'Terminated - {}.py'.format(self.command)
        elif returncode == -9:
            status = 'Killed - {}.py'.format(self.command)
        elif returncode == -6:
            status = 'Aborted - {}.py'.format(self.command)
        else:
            status = 'Failed - {}.py. Return Code: {}'.format(self.command, returncode)
        self.utils.guitext['status'].set(status)

            self.process.terminate()
            self.process.wait(timeout=10)
            print('Terminated')
        except TimeoutExpired:
            print('Termination timed out. Killing Process...')
            self.process.kill()
            print('Killed')

    def set_final_status(self, returncode):
        """ Set the status bar output based on subprocess return code """
        if returncode == 0 or returncode == 3221225786:
            status = 'Ready'
        elif returncode == -15:
            status = 'Terminated - {}.py'.format(self.command)
        elif returncode == -9:
            status = 'Killed - {}.py'.format(self.command)
        elif returncode == -6:
            status = 'Aborted - {}.py'.format(self.command)
        else:
            status = 'Failed - {}.py. Return Code: {}'.format(self.command, returncode)
        self.utils.guitext['status'].set(status)

            self.process.terminate()
            self.process.wait(timeout=10)
            print('Terminated')
        except TimeoutExpired:
            print('Termination timed out. Killing Process...')
            self.process.kill()
            print('Killed')

    def set_final_status(self, returncode):
        """ Set the status bar output based on subprocess return code """
        if returncode == 0 or returncode == 3221225786:
            status = 'Ready'
        elif returncode == -15:
            status = 'Terminated - {}.py'.format(self.command)
        elif returncode == -9:
            status = 'Killed - {}.py'.format(self.command)
        elif returncode == -6:
            status = 'Aborted - {}.py'.format(self.command)
        else:
            status = 'Failed - {}.py. Return Code: {}'.format(self.command, returncode)
        self.utils.guitext['status'].set(status)

            self.process.terminate()
            self.process.wait(timeout=10)
            print('Terminated')
        except TimeoutExpired:
            print('Termination timed out. Killing Process...')
            self.process.kill()
            print('Killed')

    def set_final_status(self, returncode):
        """ Set the status bar output based on subprocess return code """
        if returncode == 0 or returncode == 3221225786:
            status = 'Ready'
        elif returncode == -15:
            status = 'Terminated - {}.py'.format(self.command)
        elif returncode == -9:
            status = 'Killed - {}.py'.format(self.command)
        elif returncode == -6:
            status = 'Aborted - {}.py'.format(self.command)
        else:
            status = 'Failed - {}.py. Return Code: {}'.format(self.command, returncode)
        self.utils.guitext['status'].set(status)

            self.process.terminate()
            self.process.wait(timeout=10)
            print('Terminated')
        except TimeoutExpired:
            print('Termination timed out. Killing Process...')
            self.process.kill()
            print('Killed')

    def set_final_status(self, returncode):
        """ Set the status bar output based on subprocess return code """
        if returncode == 0 or returncode == 3221225786:
            status = 'Ready'
        elif returncode == -15:
            status = 'Terminated - {}.py'.format(self.command)
        elif returncode == -9:
            status = 'Killed - {}.py'.format(self.command)
        elif returncode == -6:
            status = 'Aborted - {}.py'.format(self.command)
        else:
            status = 'Failed - {}.py. Return Code: {}'.format(self.command, returncode)
        self.utils.guitext['status'].set(status)

            self.process.terminate()
            self.process.wait(timeout=10)
            print('Terminated')
        except TimeoutExpired:
            print('Termination timed out. Killing Process...')
            self.process.kill()
            print('Killed')

    def set_final_status(self, returncode):
        """ Set the status bar output based on subprocess return code """
        if returncode == 0 or returncode == 3221225786:
            status = 'Ready'
        elif returncode == -15:
            status = 'Terminated - {}.py'.format(self.command)
        elif returncode == -9:
            status = 'Killed - {}.py'.format(self.command)
        elif returncode == -6:
            status = 'Aborted - {}.py'.format(self.command)
        else:
            status = 'Failed - {}.py. Return Code: {}'.format(self.command, returncode)
        self.utils.guitext['status'].set(status)

            self.process.terminate()
            self.process.wait(timeout=10)
            print('Terminated')
        except TimeoutExpired:
            print('Termination timed out. Killing Process...')
            self.process.kill()
            print('Killed')

    def set_final_status(self, returncode):
        """ Set the status bar output based on subprocess return code """
        if returncode == 0 or returncode == 3221225786:
            status = 'Ready'
        elif returncode == -15:
            status = 'Terminated - {}.py'.format(self.command)
        elif returncode == -9:
            status = 'Killed - {}.py'.format(self.command)
        elif returncode == -6:
            status = 'Aborted - {}.py'.format(self.command)
        else:
            status = 'Failed - {}.py. Return Code: {}'.format(self.command, returncode)
        self.utils.guitext['status'].set(status)

            self.process.terminate()
            self.process.wait(timeout=10)
            print('Terminated')
        except TimeoutExpired:
            print('Termination timed out. Killing Process...')
            self.process.kill()
            print('Killed')

    def set_final_status(self, returncode):
        """ Set the status bar output based on subprocess return code """
        if returncode == 0 or returncode == 3221225786:
            status = 'Ready'
        elif returncode == -15:
            status = 'Terminated - {}.py'.format(self.command)
        elif returncode == -9:
            status = 'Killed - {}.py'.format(self.command)
        elif returncode == -6:
            status = 'Aborted - {}.py'.format(self.command)
        else:
            status = 'Failed - {}.py. Return Code: {}'.format(self.command, returncode)
        self.utils.guitext['status'].set(status)

  
  class TKGui(object):
      ''' Main GUI Control '''
      def __init__ (self, subparser, subparsers, parser, command, description='default'):
      # Don't try to load the GUI if there is no display or there are problems importing tkinter
keep keep keep keep replace replace replace replace replace replace replace replace keep keep keep keep keep
 GUI v0.2.1b (#352)

* Code refactor

* Console Added

* Add graphing with matplotlib

* Add GUI preview support

* Improve import handling.

* Add GUI integration for tools.py (Launch tools.py with the gui command)

* Reformat to conform to PEP8.

* Add Tooltips, 

* Make panels user adjustable

* Fix convert.py Sharpen default value 
scripts/gui.py