diff --git a/scripts/GUI_debug.py b/scripts/GUI_debug.py index d698c105c8e4ffa3c5dd95516f5b4b0f3c3e00ad..b72ef61c0da3b9e89e0c05ee8e62768d3a0dead5 100644 --- a/scripts/GUI_debug.py +++ b/scripts/GUI_debug.py @@ -1,18 +1,25 @@ import tkinter as tk from tkinter import ttk, messagebox import tkinter.filedialog +import subprocess +import sys import os -import configparser +from PIL import Image, ImageTk class ModuleDebugGUI: def __init__(self): self.window = tk.Tk() - self.window.title("Pipeline Debug Tool - Config & Paths") + self.window.title("Pipeline Debug Tool") + self.window.geometry("800x600") # Initialize paths self.SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) self.ROOT_DIR = os.path.dirname(self.SCRIPT_DIR) + # Input/output paths + self.input_file_path = None + self.shifted_image_path = os.path.join(self.SCRIPT_DIR, "shifted_t.png") + # Initialize directories and file paths self.setup_directories() @@ -20,8 +27,14 @@ class ModuleDebugGUI: self.config = {} self.read_config() - self.setup_ui() + # Create notebook for tabs + self.notebook = ttk.Notebook(self.window) + self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + # Create tabs + self.setup_config_tab() + self.setup_shifter_tab() + def setup_directories(self): self.directories = { 'scriptDir': self.SCRIPT_DIR, @@ -57,42 +70,41 @@ class ModuleDebugGUI: return False return True - def setup_ui(self): - # Main container - main_frame = ttk.Frame(self.window, padding="10") - main_frame.pack(fill=tk.BOTH, expand=True) + def setup_config_tab(self): + config_tab = ttk.Frame(self.notebook) + self.notebook.add(config_tab, text='Configuration Check') # Config section - config_frame = ttk.LabelFrame(main_frame, text="Config Values", padding="5") - config_frame.pack(fill=tk.X, pady=5) + config_frame = ttk.LabelFrame(config_tab, text="Config Values", padding="5") + config_frame.pack(fill=tk.X, pady=5, padx=5) self.config_text = tk.Text(config_frame, height=6, wrap=tk.WORD) self.config_text.pack(fill=tk.X) # Directory paths section - dir_frame = ttk.LabelFrame(main_frame, text="Directory Paths", padding="5") - dir_frame.pack(fill=tk.X, pady=5) + dir_frame = ttk.LabelFrame(config_tab, text="Directory Paths", padding="5") + dir_frame.pack(fill=tk.X, pady=5, padx=5) self.dir_text = tk.Text(dir_frame, height=8, wrap=tk.WORD) self.dir_text.pack(fill=tk.X) # File paths section - file_frame = ttk.LabelFrame(main_frame, text="File Paths", padding="5") - file_frame.pack(fill=tk.X, pady=5) + file_frame = ttk.LabelFrame(config_tab, text="File Paths", padding="5") + file_frame.pack(fill=tk.X, pady=5, padx=5) self.file_text = tk.Text(file_frame, height=5, wrap=tk.WORD) self.file_text.pack(fill=tk.X) # Path verification section - verify_frame = ttk.LabelFrame(main_frame, text="Path Verification", padding="5") - verify_frame.pack(fill=tk.X, pady=5) + verify_frame = ttk.LabelFrame(config_tab, text="Path Verification", padding="5") + verify_frame.pack(fill=tk.X, pady=5, padx=5) self.verify_text = tk.Text(verify_frame, height=8, wrap=tk.WORD) self.verify_text.pack(fill=tk.X) # Buttons - button_frame = ttk.Frame(main_frame) - button_frame.pack(fill=tk.X, pady=5) + button_frame = ttk.Frame(config_tab) + button_frame.pack(fill=tk.X, pady=5, padx=5) ttk.Button( button_frame, @@ -115,6 +127,122 @@ class ModuleDebugGUI: # Initial display self.refresh_all() + def setup_shifter_tab(self): + shifter_tab = ttk.Frame(self.notebook) + self.notebook.add(shifter_tab, text='Image Shifter') + + # Split into left and right frames + left_frame = ttk.Frame(shifter_tab) + left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) + + right_frame = ttk.Frame(shifter_tab) + right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5, pady=5) + + # Control section (left frame) + control_frame = ttk.LabelFrame(left_frame, text="Controls", padding="5") + control_frame.pack(fill=tk.X, pady=5) + + # Input file selection + input_frame = ttk.Frame(control_frame) + input_frame.pack(fill=tk.X, pady=5) + + self.input_label = ttk.Label(input_frame, text="No input file selected") + self.input_label.pack(side=tk.LEFT, padx=5) + + ttk.Button( + input_frame, + text="Select Input File", + command=self.select_input_file + ).pack(side=tk.RIGHT, padx=5) + + # Output file display + output_frame = ttk.Frame(control_frame) + output_frame.pack(fill=tk.X, pady=5) + + ttk.Label(output_frame, text="Output will be saved as:").pack(side=tk.LEFT, padx=5) + self.output_label = ttk.Label(output_frame, text=os.path.basename(self.shifted_image_path)) + self.output_label.pack(side=tk.LEFT, padx=5) + + # Environment info + env_frame = ttk.Frame(control_frame) + env_frame.pack(fill=tk.X, pady=5) + + ttk.Label(env_frame, text="Using conda environment:").pack(side=tk.LEFT, padx=5) + self.env_label = ttk.Label(env_frame, text=self.config.get('materialEnv', 'Not found')) + self.env_label.pack(side=tk.LEFT, padx=5) + + # Control buttons + button_frame = ttk.Frame(control_frame) + button_frame.pack(fill=tk.X, pady=5) + + ttk.Button( + button_frame, + text="Run Image Shifter", + command=self.run_shifter + ).pack(side=tk.RIGHT, padx=5) + + ttk.Button( + button_frame, + text="Clear Status", + command=self.clear_status + ).pack(side=tk.RIGHT, padx=5) + + # Image preview section (right frame) + preview_frame = ttk.LabelFrame(right_frame, text="Image Preview", padding="5") + preview_frame.pack(fill=tk.BOTH, expand=True) + + # Input image preview + input_preview_frame = ttk.LabelFrame(preview_frame, text="Input Image") + input_preview_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) + + self.input_preview = ttk.Label(input_preview_frame) + self.input_preview.pack(padx=5, pady=5) + + # Output image preview + output_preview_frame = ttk.LabelFrame(preview_frame, text="Shifted Image") + output_preview_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) + + self.output_preview = ttk.Label(output_preview_frame) + self.output_preview.pack(padx=5, pady=5) + + # Status section at the bottom of left frame + status_frame = ttk.LabelFrame(left_frame, text="Status", padding="5") + status_frame.pack(fill=tk.BOTH, expand=True, pady=5) + + # Add scrollbar to status + status_scroll = ttk.Scrollbar(status_frame) + status_scroll.pack(side=tk.RIGHT, fill=tk.Y) + + self.status_text = tk.Text(status_frame, height=10, wrap=tk.WORD, yscrollcommand=status_scroll.set) + self.status_text.pack(fill=tk.BOTH, expand=True) + status_scroll.config(command=self.status_text.yview) + + # Add these new methods to handle image preview + def update_image_preview(self): + preview_size = (300, 300) # Adjust size as needed + + # Update input image preview if exists + if self.input_file_path and os.path.exists(self.input_file_path): + try: + input_img = Image.open(self.input_file_path) + input_img.thumbnail(preview_size) + input_photo = ImageTk.PhotoImage(input_img) + self.input_preview.configure(image=input_photo) + self.input_preview.image = input_photo # Keep a reference + except Exception as e: + self.update_status(f"Failed to load input image preview: {str(e)}") + + # Update output image preview if exists + if os.path.exists(self.shifted_image_path): + try: + output_img = Image.open(self.shifted_image_path) + output_img.thumbnail(preview_size) + output_photo = ImageTk.PhotoImage(output_img) + self.output_preview.configure(image=output_photo) + self.output_preview.image = output_photo # Keep a reference + except Exception as e: + self.update_status(f"Failed to load output image preview: {str(e)}") + def refresh_all(self): self.refresh_config_display() self.refresh_directory_display() @@ -158,6 +286,23 @@ class ModuleDebugGUI: self.verify_text.tag_config("green", foreground="green") self.verify_text.tag_config("red", foreground="red") + def select_input_file(self): + self.input_file_path = tkinter.filedialog.askopenfilename( + filetypes=[("Image files", "*.png *.jpg *.jpeg")] + ) + if self.input_file_path: + self.input_file_path = os.path.normpath(self.input_file_path) + self.input_label.config(text=os.path.basename(self.input_file_path)) + self.update_status(f"Selected input file: {self.input_file_path}") + self.update_image_preview() + + def update_status(self, message): + self.status_text.insert(tk.END, f"{message}\n") + self.status_text.see(tk.END) + + def clear_status(self): + self.status_text.delete(1.0, tk.END) + def save_debug_info(self): debug_info = "=== Pipeline Debug Information ===\n\n" @@ -177,7 +322,6 @@ class ModuleDebugGUI: status = "exists" if exists else "missing" debug_info += f"{key}: {path} ({status})\n" - # Save to file try: with open("pipeline_debug_info.txt", "w") as f: f.write(debug_info) @@ -185,6 +329,48 @@ class ModuleDebugGUI: except Exception as e: messagebox.showerror("Error", f"Failed to save debug info: {str(e)}") + def run_shifter(self): + if not self.input_file_path: + messagebox.showwarning("Warning", "Please select an input file first") + return + + self.update_status("\nRunning image shifter...") + + try: + # Construct the command + cmd = f'''call "{self.config["condaDir"]}\\condabin\\activate.bat" {self.config["materialEnv"]} && python "{os.path.join(self.SCRIPT_DIR, "shifter.py")}" "{self.input_file_path}" "{self.shifted_image_path}" && call "{self.config["condaDir"]}\\condabin\\deactivate.bat"''' + + # Run the command + self.update_status(f"Executing command:\n{cmd}\n") + + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True, + text=True + ) + stdout, stderr = process.communicate() + + if process.returncode == 0: + self.update_status("Image shifter completed successfully") + if stdout: + self.update_status("Output:\n" + stdout) + + if os.path.exists(self.shifted_image_path): + self.update_status(f"Shifted image saved to: {self.shifted_image_path}") + self.update_image_preview() # Update the preview after successful completion + else: + self.update_status("Warning: Output file not found!") + else: + self.update_status("Image shifter failed with error:\n" + stderr) + messagebox.showerror("Error", f"Command failed:\n\n{stderr}") + + except Exception as e: + error_msg = f"Failed to run image shifter: {str(e)}" + self.update_status(error_msg) + messagebox.showerror("Error", error_msg) + def run(self): self.window.mainloop()