1
0
Fork 0
mirror of https://github.com/deepfakes/faceswap synced 2025-06-08 20:13:52 -04:00
faceswap/lib/gui/display_page.py
torzdf e1fca14716 Add Restore Model Tool
Tool: Add tool to restore models from backup
Snapshot: Create snapshot based on total iterations rather than session iterations
Models: Move backup/snapshot functions to lib/model
Training: Output average loss since last save at each save iteration
GUI: display_page.py: minor logging update
2019-07-01 23:28:31 +00:00

273 lines
9.7 KiB
Python

#!/usr/bin python3
""" Display Page parent classes for display section of the Faceswap GUI """
import logging
import tkinter as tk
from tkinter import ttk
from .tooltip import Tooltip
from .utils import get_images
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
class DisplayPage(ttk.Frame): # pylint: disable=too-many-ancestors
""" Parent frame holder for each tab.
Defines uniform structure for each tab to inherit from """
def __init__(self, parent, tabname, helptext):
logger.debug("Initializing %s: (tabname: '%s', helptext: %s)",
self.__class__.__name__, tabname, helptext)
ttk.Frame.__init__(self, parent)
self.pack(fill=tk.BOTH, side=tk.TOP, anchor=tk.NW)
self.runningtask = parent.runningtask
self.helptext = helptext
self.tabname = tabname
self.vars = {"info": tk.StringVar()}
self.add_optional_vars(self.set_vars())
self.subnotebook = self.add_subnotebook()
self.optsframe = self.add_options_frame()
self.add_options_info()
self.add_frame_separator()
self.set_mainframe_single_tab_style()
parent.add(self, text=self.tabname.title())
logger.debug("Initialized %s", self.__class__.__name__,)
def add_optional_vars(self, varsdict):
""" Add page specific variables """
if isinstance(varsdict, dict):
for key, val in varsdict.items():
logger.debug("Adding: (%s: %s)", key, val)
self.vars[key] = val
@staticmethod
def set_vars():
""" Override to return a dict of page specific variables """
return dict()
def add_subnotebook(self):
""" Add the main frame notebook """
logger.debug("Adding subnotebook")
notebook = ttk.Notebook(self)
notebook.pack(side=tk.TOP, anchor=tk.NW, fill=tk.BOTH, expand=True)
return notebook
def add_options_frame(self):
""" Add the display tab options """
logger.debug("Adding options frame")
optsframe = ttk.Frame(self)
optsframe.pack(side=tk.BOTTOM, padx=5, pady=5, fill=tk.X)
return optsframe
def add_options_info(self):
""" Add the info bar """
logger.debug("Adding options info")
lblinfo = ttk.Label(self.optsframe,
textvariable=self.vars["info"],
anchor=tk.W,
width=70)
lblinfo.pack(side=tk.LEFT, padx=5, pady=5, anchor=tk.W)
def set_info(self, msg):
""" Set the info message """
logger.debug("Setting info: %s", msg)
self.vars["info"].set(msg)
def add_frame_separator(self):
""" Add a separator between top and bottom frames """
logger.debug("Adding frame seperator")
sep = ttk.Frame(self, height=2, relief=tk.RIDGE)
sep.pack(fill=tk.X, pady=(5, 0), side=tk.BOTTOM)
@staticmethod
def set_mainframe_single_tab_style():
""" Configure ttk notebook style to represent a single frame """
logger.debug("Setting main frame single tab style")
nbstyle = ttk.Style()
nbstyle.configure("single.TNotebook", borderwidth=0)
nbstyle.layout("single.TNotebook.Tab", [])
def subnotebook_add_page(self, tabtitle, widget=None):
""" Add a page to the sub notebook """
logger.debug("Adding subnotebook page: %s", tabtitle)
frame = widget if widget else ttk.Frame(self.subnotebook)
frame.pack(padx=5, pady=5, fill=tk.BOTH, expand=True)
self.subnotebook.add(frame, text=tabtitle)
self.subnotebook_configure()
return frame
def subnotebook_configure(self):
""" Configure notebook to display or hide tabs """
if len(self.subnotebook.children) == 1:
logger.debug("Setting single page style")
self.subnotebook.configure(style="single.TNotebook")
else:
logger.debug("Setting multi page style")
self.subnotebook.configure(style="TNotebook")
def subnotebook_hide(self):
""" Hide the subnotebook. Used for hiding
Optional displays """
if self.subnotebook and self.subnotebook.winfo_ismapped():
logger.debug("Hiding subnotebook")
self.subnotebook.pack_forget()
self.subnotebook.destroy()
self.subnotebook = None
def subnotebook_show(self):
""" Show subnotebook. Used for displaying
Optional displays """
if not self.subnotebook:
logger.debug("Showing subnotebook")
self.subnotebook = self.add_subnotebook()
def subnotebook_get_widgets(self):
""" Return each widget that sits within each
subnotebook frame """
logger.debug("Getting subnotebook widgets")
for child in self.subnotebook.winfo_children():
for widget in child.winfo_children():
yield widget
def subnotebook_get_titles_ids(self):
""" Return tabs ids and titles """
tabs = dict()
for tab_id in range(0, self.subnotebook.index("end")):
tabs[self.subnotebook.tab(tab_id, "text")] = tab_id
logger.debug(tabs)
return tabs
def subnotebook_page_from_id(self, tab_id):
""" Return subnotebook tab widget from it's ID """
tab_name = self.subnotebook.tabs()[tab_id].split(".")[-1]
logger.debug(tab_name)
return self.subnotebook.children[tab_name]
class DisplayOptionalPage(DisplayPage): # pylint: disable=too-many-ancestors
""" Parent Context Sensitive Display Tab """
def __init__(self, parent, tabname, helptext, waittime, command=None):
logger.debug("%s: OptionalPage args: (waittime: %s, command: %s)",
self.__class__.__name__, waittime, command)
DisplayPage.__init__(self, parent, tabname, helptext)
self.command = command
self.display_item = None
self.set_info_text()
self.add_options()
parent.select(self)
self.update_idletasks()
self.update_page(waittime)
@staticmethod
def set_vars():
""" Analysis specific vars """
enabled = tk.BooleanVar()
enabled.set(True)
ready = tk.BooleanVar()
ready.set(False)
modified = tk.DoubleVar()
modified.set(None)
tk_vars = {"enabled": enabled,
"ready": ready,
"modified": modified}
logger.debug(tk_vars)
return tk_vars
# INFO LABEL
def set_info_text(self):
""" Set waiting for display text """
if not self.vars["enabled"].get():
msg = "{} disabled".format(self.tabname.title())
elif self.vars["enabled"].get() and not self.vars["ready"].get():
msg = "Waiting for {}...".format(self.tabname)
else:
msg = "Displaying {}".format(self.tabname)
logger.debug(msg)
self.set_info(msg)
# DISPLAY OPTIONS BAR
def add_options(self):
""" Add the additional options """
self.add_option_save()
self.add_option_enable()
def add_option_save(self):
""" Add save button to save page output to file """
logger.debug("Adding save option")
btnsave = ttk.Button(self.optsframe,
image=get_images().icons["save"],
command=self.save_items)
btnsave.pack(padx=2, side=tk.RIGHT)
Tooltip(btnsave,
text="Save {}(s) to file".format(self.tabname),
wraplength=200)
def add_option_enable(self):
""" Add checkbutton to enable/disable page """
logger.debug("Adding enable option")
chkenable = ttk.Checkbutton(self.optsframe,
variable=self.vars["enabled"],
text="Enable {}".format(self.tabname),
command=self.on_chkenable_change)
chkenable.pack(side=tk.RIGHT, padx=5, anchor=tk.W)
Tooltip(chkenable,
text="Enable or disable {} display".format(self.tabname),
wraplength=200)
def save_items(self):
""" Save items. Override for display specific saving """
raise NotImplementedError()
def on_chkenable_change(self):
""" Update the display immediately on a checkbutton change """
logger.debug("Enabled checkbox changed")
if self.vars["enabled"].get():
self.subnotebook_show()
else:
self.subnotebook_hide()
self.set_info_text()
def update_page(self, waittime):
""" Update the latest preview item """
if not self.runningtask.get():
return
if self.vars["enabled"].get():
logger.trace("Updating page")
self.display_item_set()
self.load_display()
self.after(waittime, lambda t=waittime: self.update_page(t))
def display_item_set(self):
""" Override for display specific loading """
raise NotImplementedError()
def load_display(self):
""" Load the display """
if not self.display_item:
return
logger.debug("Loading display")
self.display_item_process()
self.vars["ready"].set(True)
self.set_info_text()
def display_item_process(self):
""" Override for display specific loading """
raise NotImplementedError()
def close(self):
""" Called when the parent notebook is shutting down
Children must be destroyed as forget only hides display
Override for page specific shutdown """
for child in self.winfo_children():
logger.debug("Destroying child: %s", child)
child.destroy()