diff --git a/VocalRemover.py b/VocalRemover.py deleted file mode 100644 index 9fd172b..0000000 --- a/VocalRemover.py +++ /dev/null @@ -1,786 +0,0 @@ -# GUI modules -import tkinter as tk -import tkinter.ttk as ttk -import tkinter.messagebox -import tkinter.filedialog -import tkinter.font -from tkinterdnd2 import TkinterDnD, DND_FILES # Enable Drag & Drop -from datetime import datetime -# Images -from PIL import Image -from PIL import ImageTk -import pickle # Save Data -# Other Modules -import subprocess # Run python file -# Pathfinding -import pathlib -import sys -import os -import subprocess -from collections import defaultdict -# Used for live text displaying -import queue -import threading # Run the algorithm inside a thread - - -from pathlib import Path - -import inference_v5 -import inference_v5_ensemble -# import win32gui, win32con - -# the_program_to_hide = win32gui.GetForegroundWindow() -# win32gui.ShowWindow(the_program_to_hide , win32con.SW_HIDE) - -# Change the current working directory to the directory -# this file sits in -if getattr(sys, 'frozen', False): - # If the application is run as a bundle, the PyInstaller bootloader - # extends the sys module by a flag frozen=True and sets the app - # path into variable _MEIPASS'. - base_path = sys._MEIPASS -else: - base_path = os.path.dirname(os.path.abspath(__file__)) - -os.chdir(base_path) # Change the current working directory to the base path - -instrumentalModels_dir = os.path.join(base_path, 'models') -banner_path = os.path.join(base_path, 'img', 'UVR-banner.png') -efile_path = os.path.join(base_path, 'img', 'file.png') -DEFAULT_DATA = { - 'exportPath': '', - 'inputPaths': [], - 'gpu': False, - 'postprocess': False, - 'tta': False, - 'save': True, - 'output_image': False, - 'window_size': '512', - 'agg': 10, - 'modelFolder': False, - 'modelInstrumentalLabel': '', - 'aiModel': 'Single Model', - 'ensChoose': 'HP1 Models', - 'useModel': 'instrumental', - 'lastDir': None, -} - -def open_image(path: str, size: tuple = None, keep_aspect: bool = True, rotate: int = 0) -> ImageTk.PhotoImage: - """ - Open the image on the path and apply given settings\n - Paramaters: - path(str): - Absolute path of the image - size(tuple): - first value - width - second value - height - keep_aspect(bool): - keep aspect ratio of image and resize - to maximum possible width and height - (maxima are given by size) - rotate(int): - clockwise rotation of image - Returns(ImageTk.PhotoImage): - Image of path - """ - img = Image.open(path).convert(mode='RGBA') - ratio = img.height/img.width - img = img.rotate(angle=-rotate) - if size is not None: - size = (int(size[0]), int(size[1])) - if keep_aspect: - img = img.resize((size[0], int(size[0] * ratio)), Image.ANTIALIAS) - else: - img = img.resize(size, Image.ANTIALIAS) - return ImageTk.PhotoImage(img) - -def save_data(data): - """ - Saves given data as a .pkl (pickle) file - - Paramters: - data(dict): - Dictionary containing all the necessary data to save - """ - # Open data file, create it if it does not exist - with open('data.pkl', 'wb') as data_file: - pickle.dump(data, data_file) - -def load_data() -> dict: - """ - Loads saved pkl file and returns the stored data - - Returns(dict): - Dictionary containing all the saved data - """ - try: - with open('data.pkl', 'rb') as data_file: # Open data file - data = pickle.load(data_file) - - return data - except (ValueError, FileNotFoundError): - # Data File is corrupted or not found so recreate it - save_data(data=DEFAULT_DATA) - - return load_data() - -def drop(event, accept_mode: str = 'files'): - """ - Drag & Drop verification process - """ - path = event.data - - if accept_mode == 'folder': - path = path.replace('{', '').replace('}', '') - if not os.path.isdir(path): - tk.messagebox.showerror(title='Invalid Folder', - message='Your given export path is not a valid folder!') - return - # Set Variables - root.exportPath_var.set(path) - elif accept_mode == 'files': - # Clean path text and set path to the list of paths - path = path.replace('{', '') - path = path.split('} ') - path[-1] = path[-1].replace('}', '') - # Set Variables - root.inputPaths = path - root.update_inputPaths() - else: - # Invalid accept mode - return - -class ThreadSafeConsole(tk.Text): - """ - Text Widget which is thread safe for tkinter - """ - def __init__(self, master, **options): - tk.Text.__init__(self, master, **options) - self.queue = queue.Queue() - self.update_me() - - def write(self, line): - self.queue.put(line) - - def clear(self): - self.queue.put(None) - - def update_me(self): - self.configure(state=tk.NORMAL) - try: - while 1: - line = self.queue.get_nowait() - if line is None: - self.delete(1.0, tk.END) - else: - self.insert(tk.END, str(line)) - self.see(tk.END) - self.update_idletasks() - except queue.Empty: - pass - self.configure(state=tk.DISABLED) - self.after(100, self.update_me) - -class MainWindow(TkinterDnD.Tk): - # --Constants-- - # Layout - IMAGE_HEIGHT = 140 - FILEPATHS_HEIGHT = 80 - OPTIONS_HEIGHT = 190 - CONVERSIONBUTTON_HEIGHT = 35 - COMMAND_HEIGHT = 200 - PROGRESS_HEIGHT = 26 - PADDING = 10 - - COL1_ROWS = 6 - COL2_ROWS = 6 - COL3_ROWS = 6 - - def __init__(self): - # Run the __init__ method on the tk.Tk class - super().__init__() - # Calculate window height - height = self.IMAGE_HEIGHT + self.FILEPATHS_HEIGHT + self.OPTIONS_HEIGHT - height += self.CONVERSIONBUTTON_HEIGHT + self.COMMAND_HEIGHT + self.PROGRESS_HEIGHT - height += self.PADDING * 5 # Padding - - # --Window Settings-- - self.title('Vocal Remover') - # Set Geometry and Center Window - self.geometry('{width}x{height}+{xpad}+{ypad}'.format( - width=620, - height=height, - xpad=int(self.winfo_screenwidth()/2 - 550/2), - ypad=int(self.winfo_screenheight()/2 - height/2 - 30))) - self.configure(bg='#000000') # Set background color to black - self.protocol("WM_DELETE_WINDOW", self.save_values) - self.resizable(False, False) - self.update() - - # --Variables-- - self.logo_img = open_image(path=banner_path, - size=(self.winfo_width(), 9999)) - self.efile_img = open_image(path=efile_path, - size=(20, 20)) - self.instrumentalLabel_to_path = defaultdict(lambda: '') - self.lastInstrumentalModels = [] - # -Tkinter Value Holders- - data = load_data() - # Paths - self.exportPath_var = tk.StringVar(value=data['exportPath']) - self.inputPaths = data['inputPaths'] - # Processing Options - self.gpuConversion_var = tk.BooleanVar(value=data['gpu']) - self.postprocessing_var = tk.BooleanVar(value=data['postprocess']) - self.tta_var = tk.BooleanVar(value=data['tta']) - self.save_var = tk.BooleanVar(value=data['save']) - self.outputImage_var = tk.BooleanVar(value=data['output_image']) - # Models - self.instrumentalModel_var = tk.StringVar(value=data['modelInstrumentalLabel']) - # Model Test Mode - self.modelFolder_var = tk.BooleanVar(value=data['modelFolder']) - # Constants - self.winSize_var = tk.StringVar(value=data['window_size']) - self.agg_var = tk.StringVar(value=data['agg']) - # Choose Conversion Method - self.aiModel_var = tk.StringVar(value=data['aiModel']) - self.last_aiModel = self.aiModel_var.get() - # Choose Ensemble - self.ensChoose_var = tk.StringVar(value=data['ensChoose']) - self.last_ensChoose = self.ensChoose_var.get() - # Other - self.inputPathsEntry_var = tk.StringVar(value='') - self.lastDir = data['lastDir'] # nopep8 - self.progress_var = tk.IntVar(value=0) - # Font - self.font = tk.font.Font(family='Microsoft JhengHei', size=9, weight='bold') - # --Widgets-- - self.create_widgets() - self.configure_widgets() - self.bind_widgets() - self.place_widgets() - self.update_available_models() - self.update_states() - self.update_loop() - - # -Widget Methods- - def create_widgets(self): - """Create window widgets""" - self.title_Label = tk.Label(master=self, bg='black', - image=self.logo_img, compound=tk.TOP) - self.filePaths_Frame = tk.Frame(master=self, bg='black') - self.fill_filePaths_Frame() - - self.options_Frame = tk.Frame(master=self, bg='black') - self.fill_options_Frame() - - self.conversion_Button = ttk.Button(master=self, - text='Start Conversion', - command=self.start_conversion) - self.efile_Button = ttk.Button(master=self, - image=self.efile_img, - command=self.open_newModel_filedialog) - - self.progressbar = ttk.Progressbar(master=self, - variable=self.progress_var) - - self.command_Text = ThreadSafeConsole(master=self, - background='#a0a0a0', - borderwidth=0,) - self.command_Text.write(f'COMMAND LINE [{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}]') # nopep8 - - def configure_widgets(self): - """Change widget styling and appearance""" - - ttk.Style().configure('TCheckbutton', background='black', - font=self.font, foreground='white') - ttk.Style().configure('TRadiobutton', background='black', - font=self.font, foreground='white') - ttk.Style().configure('T', font=self.font, foreground='white') - - def bind_widgets(self): - """Bind widgets to the drag & drop mechanic""" - self.filePaths_saveTo_Button.drop_target_register(DND_FILES) - self.filePaths_saveTo_Entry.drop_target_register(DND_FILES) - self.filePaths_musicFile_Button.drop_target_register(DND_FILES) - self.filePaths_musicFile_Entry.drop_target_register(DND_FILES) - self.filePaths_saveTo_Button.dnd_bind('<>', - lambda e: drop(e, accept_mode='folder')) - self.filePaths_saveTo_Entry.dnd_bind('<>', - lambda e: drop(e, accept_mode='folder')) - self.filePaths_musicFile_Button.dnd_bind('<>', - lambda e: drop(e, accept_mode='files')) - self.filePaths_musicFile_Entry.dnd_bind('<>', - lambda e: drop(e, accept_mode='files')) - - def place_widgets(self): - """Place main widgets""" - self.title_Label.place(x=-2, y=-2) - self.filePaths_Frame.place(x=10, y=155, width=-20, height=self.FILEPATHS_HEIGHT, - relx=0, rely=0, relwidth=1, relheight=0) - self.options_Frame.place(x=25, y=250, width=-50, height=self.OPTIONS_HEIGHT, - relx=0, rely=0, relwidth=1, relheight=0) - self.conversion_Button.place(x=10, y=self.IMAGE_HEIGHT + self.FILEPATHS_HEIGHT + self.OPTIONS_HEIGHT + self.PADDING*2, width=-20 - 40, height=self.CONVERSIONBUTTON_HEIGHT, - relx=0, rely=0, relwidth=1, relheight=0) - self.efile_Button.place(x=-10 - 35, y=self.IMAGE_HEIGHT + self.FILEPATHS_HEIGHT + self.OPTIONS_HEIGHT + self.PADDING*2, width=35, height=self.CONVERSIONBUTTON_HEIGHT, - relx=1, rely=0, relwidth=0, relheight=0) - self.command_Text.place(x=15, y=self.IMAGE_HEIGHT + self.FILEPATHS_HEIGHT + self.OPTIONS_HEIGHT + self.CONVERSIONBUTTON_HEIGHT + self.PADDING*3, width=-30, height=self.COMMAND_HEIGHT, - relx=0, rely=0, relwidth=1, relheight=0) - self.progressbar.place(x=25, y=self.IMAGE_HEIGHT + self.FILEPATHS_HEIGHT + self.OPTIONS_HEIGHT + self.CONVERSIONBUTTON_HEIGHT + self.COMMAND_HEIGHT + self.PADDING*4, width=-50, height=self.PROGRESS_HEIGHT, - relx=0, rely=0, relwidth=1, relheight=0) - - def fill_filePaths_Frame(self): - """Fill Frame with neccessary widgets""" - # -Create Widgets- - # Save To Option - self.filePaths_saveTo_Button = ttk.Button(master=self.filePaths_Frame, - text='Save to', - command=self.open_export_filedialog) - self.filePaths_saveTo_Entry = ttk.Entry(master=self.filePaths_Frame, - - textvariable=self.exportPath_var, - state=tk.DISABLED - ) - # Select Music Files Option - self.filePaths_musicFile_Button = ttk.Button(master=self.filePaths_Frame, - text='Select Your Audio File(s)', - command=self.open_file_filedialog) - self.filePaths_musicFile_Entry = ttk.Entry(master=self.filePaths_Frame, - textvariable=self.inputPathsEntry_var, - state=tk.DISABLED - ) - # -Place Widgets- - # Save To Option - self.filePaths_saveTo_Button.place(x=0, y=5, width=0, height=-10, - relx=0, rely=0, relwidth=0.3, relheight=0.5) - self.filePaths_saveTo_Entry.place(x=10, y=7, width=-20, height=-14, - relx=0.3, rely=0, relwidth=0.7, relheight=0.5) - # Select Music Files Option - self.filePaths_musicFile_Button.place(x=0, y=5, width=0, height=-10, - relx=0, rely=0.5, relwidth=0.4, relheight=0.5) - self.filePaths_musicFile_Entry.place(x=10, y=7, width=-20, height=-14, - relx=0.4, rely=0.5, relwidth=0.6, relheight=0.5) - - def fill_options_Frame(self): - """Fill Frame with neccessary widgets""" - # -Create Widgets- - # -Column 1- - # GPU Selection - self.options_gpu_Checkbutton = ttk.Checkbutton(master=self.options_Frame, - text='GPU Conversion', - variable=self.gpuConversion_var, - ) - # Postprocessing - self.options_post_Checkbutton = ttk.Checkbutton(master=self.options_Frame, - text='Post-Process', - variable=self.postprocessing_var, - ) - # TTA - self.options_tta_Checkbutton = ttk.Checkbutton(master=self.options_Frame, - text='TTA', - variable=self.tta_var, - ) - # Save Ensemble Outputs - self.options_save_Checkbutton = ttk.Checkbutton(master=self.options_Frame, - text='Save All Outputs', - variable=self.save_var, - ) - # Save Image - self.options_image_Checkbutton = ttk.Checkbutton(master=self.options_Frame, - text='Output Image', - variable=self.outputImage_var, - ) - - # Model Test Mode - self.options_modelFolder_Checkbutton = ttk.Checkbutton(master=self.options_Frame, - text='Model Test Mode', - variable=self.modelFolder_var, - ) - # -Column 2- - - # Choose Conversion Method - self.options_aiModel_Label = tk.Label(master=self.options_Frame, - text='Choose Conversion Method', anchor=tk.CENTER, - background='#404040', font=self.font, foreground='white', relief="groove") - self.options_aiModel_Optionmenu = ttk.OptionMenu(self.options_Frame, - self.aiModel_var, - None, 'Single Model', 'Ensemble Mode') - # Ensemble Mode - self.options_ensChoose_Label = tk.Label(master=self.options_Frame, - text='Choose Ensemble', anchor=tk.CENTER, - background='#404040', font=self.font, foreground='white', relief="groove") - self.options_ensChoose_Optionmenu = ttk.OptionMenu(self.options_Frame, - self.ensChoose_var, - None, 'HP1 Models', 'HP2 Models', 'All HP Models', 'Vocal Models') - # -Column 3- - - # WINDOW SIZE - self.options_winSize_Label = tk.Label(master=self.options_Frame, - text='Window Size', anchor=tk.CENTER, - background='#404040', font=self.font, foreground='white', relief="groove") - self.options_winSize_Optionmenu = ttk.OptionMenu(self.options_Frame, - self.winSize_var, - None, '320', '512','1024') - - # AGG - self.options_agg_Entry = ttk.Entry(master=self.options_Frame, - textvariable=self.agg_var, justify='center') - self.options_agg_Label = tk.Label(master=self.options_Frame, - text='Aggression Setting', - background='#404040', font=self.font, foreground='white', relief="groove") - - # "Save to", "Select Your Audio File(s)"", and "Start Conversion" Button Style - s = ttk.Style() - s.configure('TButton', background='blue', foreground='black', font=('Microsoft JhengHei', '9', 'bold'), relief="groove") - - # -Column 3- - # Choose Instrumental Model - self.options_instrumentalModel_Label = tk.Label(master=self.options_Frame, - text='Choose Main Model', - background='#404040', font=self.font, foreground='white', relief="groove") - self.options_instrumentalModel_Optionmenu = ttk.OptionMenu(self.options_Frame, - self.instrumentalModel_var) - - # -Place Widgets- - - # -Column 1- - self.options_gpu_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=0, relwidth=1/3, relheight=1/self.COL1_ROWS) - self.options_post_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=1/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS) - self.options_tta_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=2/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS) - self.options_save_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=4/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS) - self.options_image_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=3/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS) - self.options_modelFolder_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=4/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS) - - # -Column 2- - self.options_instrumentalModel_Label.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=2/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - self.options_instrumentalModel_Optionmenu.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - - - self.options_ensChoose_Label.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=0/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - self.options_ensChoose_Optionmenu.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=1/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - - # Conversion Method - self.options_aiModel_Label.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=0/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - self.options_aiModel_Optionmenu.place(x=-15, y=4, width=0, height=-10, - relx=1/3, rely=1/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - - # -Column 3- - - # WINDOW - self.options_winSize_Label.place(x=35, y=6, width=-40, height=-10, - relx=2/3, rely=0, relwidth=1/3, relheight=1/self.COL3_ROWS) - self.options_winSize_Optionmenu.place(x=80, y=6, width=-133, height=-10, - relx=2/3, rely=1/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS) - - # AGG - self.options_agg_Label.place(x=35, y=6, width=-40, height=-10, - relx=2/3, rely=2/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS) - self.options_agg_Entry.place(x=80, y=6, width=-133, height=-10, - relx=2/3, rely=3/self.COL3_ROWS, relwidth=1/3, relheight=1/self.COL3_ROWS) - - # Model deselect - self.aiModel_var.trace_add('write', - lambda *args: self.deselect_models()) - - # Opening filedialogs - def open_file_filedialog(self): - """Make user select music files""" - if self.lastDir is not None: - if not os.path.isdir(self.lastDir): - self.lastDir = None - - paths = tk.filedialog.askopenfilenames( - parent=self, - title=f'Select Music Files', - initialfile='', - initialdir=self.lastDir, - ) - if paths: # Path selected - self.inputPaths = paths - self.update_inputPaths() - self.lastDir = os.path.dirname(paths[0]) - - def open_export_filedialog(self): - """Make user select a folder to export the converted files in""" - path = tk.filedialog.askdirectory( - parent=self, - title=f'Select Folder',) - if path: # Path selected - self.exportPath_var.set(path) - - def open_newModel_filedialog(self): - """Let user paste a ".pth" model to use for the vocal seperation""" - filename = self.exportPath_var.get() - - if sys.platform == "win32": - os.startfile(filename) - else: - opener = "open" if sys.platform == "darwin" else "xdg-open" - subprocess.call([opener, filename]) - - def start_conversion(self): - """ - Start the conversion for all the given mp3 and wav files - """ - # -Get all variables- - export_path = self.exportPath_var.get() - input_paths = self.inputPaths - instrumentalModel_path = self.instrumentalLabel_to_path[self.instrumentalModel_var.get()] # nopep8 - # Get constants - instrumental = self.instrumentalModel_var.get() - try: - if [bool(instrumental)].count(True) == 2: #CHECKTHIS - window_size = DEFAULT_DATA['window_size'] - agg = DEFAULT_DATA['agg'] - else: - window_size = int(self.winSize_var.get()) - agg = int(self.agg_var.get()) - ensChoose = str(self.ensChoose_var.get()) - except ValueError: # Non integer was put in entry box - tk.messagebox.showwarning(master=self, - title='Invalid Input', - message='Please make sure you only input integer numbers!') - return - except SyntaxError: # Non integer was put in entry box - tk.messagebox.showwarning(master=self, - title='Invalid Music File', - message='You have selected an invalid music file!\nPlease make sure that your files still exist and ends with either ".mp3", ".mp4", ".m4a", ".flac", ".wav"') - return - - # -Check for invalid inputs- - for path in input_paths: - if not os.path.isfile(path): - tk.messagebox.showwarning(master=self, - title='Invalid Music File', - message='You have selected an invalid music file! Please make sure that the file still exists!', - detail=f'File path: {path}') - return - if self.aiModel_var.get() == 'Single Model': - if not os.path.isfile(instrumentalModel_path): - tk.messagebox.showwarning(master=self, - title='Invalid Main Model File', - message='You have selected an invalid main model file!\nPlease make sure that your model file still exists!') - return - - if not os.path.isdir(export_path): - tk.messagebox.showwarning(master=self, - title='Invalid Export Directory', - message='You have selected an invalid export directory!\nPlease make sure that your directory still exists!') - return - - if self.aiModel_var.get() == 'Single Model': - inference = inference_v5 - elif self.aiModel_var.get() == 'Ensemble Mode': - inference = inference_v5_ensemble - else: - raise TypeError('This error should not occur.') - - # -Run the algorithm- - threading.Thread(target=inference.main, - kwargs={ - # Paths - 'input_paths': input_paths, - 'export_path': export_path, - # Processing Options - 'gpu': 0 if self.gpuConversion_var.get() else -1, - 'postprocess': self.postprocessing_var.get(), - 'tta': self.tta_var.get(), - 'save': self.save_var.get(), - 'output_image': self.outputImage_var.get(), - # Models - 'instrumentalModel': instrumentalModel_path, - 'vocalModel': '', # Always not needed - 'useModel': 'instrumental', # Always instrumental - # Model Folder - 'modelFolder': self.modelFolder_var.get(), - # Constants - 'window_size': window_size, - 'agg': agg, - 'ensChoose': ensChoose, - # Other Variables (Tkinter) - 'window': self, - 'text_widget': self.command_Text, - 'button_widget': self.conversion_Button, - 'inst_menu': self.options_instrumentalModel_Optionmenu, - 'progress_var': self.progress_var, - }, - daemon=True - ).start() - - # Models - def update_inputPaths(self): - """Update the music file entry""" - if self.inputPaths: - # Non-empty Selection - text = '; '.join(self.inputPaths) - else: - # Empty Selection - text = '' - self.inputPathsEntry_var.set(text) - - def update_loop(self): - """Update the dropdown menu""" - self.update_available_models() - - self.after(3000, self.update_loop) - - def update_available_models(self): - """ - Loop through every model (.pth) in the models directory - and add to the select your model list - """ - #temp_instrumentalModels_dir = os.path.join(instrumentalModels_dir, self.aiModel_var.get(), 'Main Models') # nopep8 - temp_instrumentalModels_dir = os.path.join(instrumentalModels_dir, 'Main Models') # nopep8 - - # Main models - new_InstrumentalModels = os.listdir(temp_instrumentalModels_dir) - if new_InstrumentalModels != self.lastInstrumentalModels: - self.instrumentalLabel_to_path.clear() - self.options_instrumentalModel_Optionmenu['menu'].delete(0, 'end') - for file_name in new_InstrumentalModels: - if file_name.endswith('.pth'): - # Add Radiobutton to the Options Menu - self.options_instrumentalModel_Optionmenu['menu'].add_radiobutton(label=file_name, - command=tk._setit(self.instrumentalModel_var, file_name)) - # Link the files name to its absolute path - self.instrumentalLabel_to_path[file_name] = os.path.join(temp_instrumentalModels_dir, file_name) # nopep8 - self.lastInstrumentalModels = new_InstrumentalModels - - def update_states(self): - """ - Vary the states for all widgets based - on certain selections - """ - if self.aiModel_var.get() == 'Single Model': - self.options_ensChoose_Label.place_forget() - self.options_ensChoose_Optionmenu.place_forget() - self.options_save_Checkbutton.configure(state=tk.DISABLED) - self.options_save_Checkbutton.place_forget() - self.options_modelFolder_Checkbutton.configure(state=tk.NORMAL) - self.options_modelFolder_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=4/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS) - self.options_instrumentalModel_Label.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - self.options_instrumentalModel_Optionmenu.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=4/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - else: - self.options_instrumentalModel_Label.place_forget() - self.options_instrumentalModel_Optionmenu.place_forget() - self.options_modelFolder_Checkbutton.place_forget() - self.options_modelFolder_Checkbutton.configure(state=tk.DISABLED) - self.options_save_Checkbutton.configure(state=tk.NORMAL) - self.options_save_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=4/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS) - self.options_ensChoose_Label.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - self.options_ensChoose_Optionmenu.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=4/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - - if self.aiModel_var.get() == 'Ensemble Mode': - self.options_instrumentalModel_Label.place_forget() - self.options_instrumentalModel_Optionmenu.place_forget() - self.options_modelFolder_Checkbutton.place_forget() - self.options_modelFolder_Checkbutton.configure(state=tk.DISABLED) - self.options_save_Checkbutton.configure(state=tk.NORMAL) - self.options_save_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=4/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS) - self.options_ensChoose_Label.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - self.options_ensChoose_Optionmenu.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=4/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - else: - self.options_ensChoose_Label.place_forget() - self.options_ensChoose_Optionmenu.place_forget() - self.options_save_Checkbutton.configure(state=tk.DISABLED) - self.options_save_Checkbutton.place_forget() - self.options_modelFolder_Checkbutton.configure(state=tk.NORMAL) - self.options_modelFolder_Checkbutton.place(x=0, y=0, width=0, height=0, - relx=0, rely=4/self.COL1_ROWS, relwidth=1/3, relheight=1/self.COL1_ROWS) - self.options_instrumentalModel_Label.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=3/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - self.options_instrumentalModel_Optionmenu.place(x=-15, y=6, width=0, height=-10, - relx=1/3, rely=4/self.COL2_ROWS, relwidth=1/3, relheight=1/self.COL2_ROWS) - - - self.update_inputPaths() - - def deselect_models(self): - """ - Run this method on version change - """ - if self.aiModel_var.get() == self.last_aiModel: - return - else: - self.last_aiModel = self.aiModel_var.get() - - self.instrumentalModel_var.set('') - self.ensChoose_var.set('HP1 Models') - - self.winSize_var.set(DEFAULT_DATA['window_size']) - self.agg_var.set(DEFAULT_DATA['agg']) - self.modelFolder_var.set(DEFAULT_DATA['modelFolder']) - - - self.update_available_models() - self.update_states() - - # def restart(self): - # """ - # Restart the application after asking for confirmation - # """ - # save = tk.messagebox.askyesno(title='Confirmation', - # message='The application will restart. Do you want to save the data?') - # if save: - # self.save_values() - # subprocess.Popen(f'..App\Python\python.exe "{__file__}"') - # exit() - - def save_values(self): - """ - Save the data of the application - """ - # Get constants - instrumental = self.instrumentalModel_var.get() - if [bool(instrumental)].count(True) == 2: #Checkthis - window_size = DEFAULT_DATA['window_size'] - agg = DEFAULT_DATA['agg'] - else: - window_size = self.winSize_var.get() - agg = self.agg_var.get() - - # -Save Data- - save_data(data={ - 'exportPath': self.exportPath_var.get(), - 'inputPaths': self.inputPaths, - 'gpu': self.gpuConversion_var.get(), - 'postprocess': self.postprocessing_var.get(), - 'tta': self.tta_var.get(), - 'save': self.save_var.get(), - 'output_image': self.outputImage_var.get(), - 'window_size': window_size, - 'agg': agg, - 'useModel': 'instrumental', - 'lastDir': self.lastDir, - 'modelFolder': self.modelFolder_var.get(), - 'modelInstrumentalLabel': self.instrumentalModel_var.get(), - 'aiModel': self.aiModel_var.get(), - 'ensChoose': self.ensChoose_var.get(), - }) - - self.destroy() - -if __name__ == "__main__": - root = MainWindow() - - root.mainloop()