Refactor PhotoTagger GUI to enhance image display and layout. Update canvas background color to match the theme, improve image resizing logic for better aspect ratio handling, and adjust grid configurations for match frames to ensure proper alignment and responsiveness. This enhances overall user experience and visual consistency across the interface.

This commit is contained in:
tanyar09 2025-09-30 15:39:51 -04:00
parent 360fcb0881
commit 15b7c10056

View File

@ -1141,10 +1141,14 @@ class PhotoTagger:
# Image display (left panel)
image_frame = ttk.Frame(left_panel)
image_frame.grid(row=0, column=0, pady=(0, 10), sticky=(tk.W, tk.E, tk.N, tk.S))
image_frame.columnconfigure(0, weight=1)
image_frame.rowconfigure(0, weight=1)
# Create canvas for image display
canvas = tk.Canvas(image_frame, width=400, height=400, bg='white')
canvas.grid(row=0, column=0)
style = ttk.Style()
canvas_bg_color = style.lookup('TFrame', 'background') or '#d9d9d9'
canvas = tk.Canvas(image_frame, width=400, height=400, bg=canvas_bg_color, highlightthickness=0)
canvas.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
# Input section (left panel)
input_frame = ttk.LabelFrame(left_panel, text="Person Identification", padding="10")
@ -1718,7 +1722,9 @@ class PhotoTagger:
clear_all_btn.config(state='disabled')
# Create canvas for similar faces with scrollbar
similar_canvas = tk.Canvas(similar_faces_frame, bg='white')
style = ttk.Style()
canvas_bg_color = style.lookup('TFrame', 'background') or '#d9d9d9'
similar_canvas = tk.Canvas(similar_faces_frame, bg=canvas_bg_color, highlightthickness=0)
similar_scrollbar = ttk.Scrollbar(similar_faces_frame, orient="vertical", command=similar_canvas.yview)
similar_scrollable_frame = ttk.Frame(similar_canvas)
@ -2171,12 +2177,43 @@ class PhotoTagger:
try:
# Load and display the face crop image
pil_image = Image.open(face_crop_path)
# Resize image to fit in window (max 400x400)
pil_image.thumbnail((400, 400), Image.Resampling.LANCZOS)
# Get canvas dimensions
canvas_width = canvas.winfo_width()
canvas_height = canvas.winfo_height()
# If canvas hasn't been rendered yet, force update and use actual size
if canvas_width <= 1 or canvas_height <= 1:
# Force the canvas to update its geometry
canvas.update_idletasks()
canvas_width = canvas.winfo_width()
canvas_height = canvas.winfo_height()
# If still not rendered, use default size
if canvas_width <= 1:
canvas_width = 400
if canvas_height <= 1:
canvas_height = 400
# Calculate scaling to fit within the canvas while maintaining aspect ratio
img_width, img_height = pil_image.size
scale_x = canvas_width / img_width
scale_y = canvas_height / img_height
# Allow slight upscaling (up to 1.2x) for better visibility, but cap to avoid excessive blurriness
max_scale = min(1.2, max(scale_x, scale_y))
scale = min(scale_x, scale_y, max_scale)
# Resize image to fill canvas
new_width = int(img_width * scale)
new_height = int(img_height * scale)
pil_image = pil_image.resize((new_width, new_height), Image.Resampling.LANCZOS)
photo = ImageTk.PhotoImage(pil_image)
# Update canvas
canvas.create_image(200, 200, image=photo)
# Center the image in the canvas
x = canvas_width // 2
y = canvas_height // 2
canvas.create_image(x, y, image=photo)
# Keep a reference to prevent garbage collection
canvas.image = photo
@ -2592,20 +2629,21 @@ class PhotoTagger:
# Bind the callback to the variable
match_var.trace('w', make_callback(match_var, current_face_id, similar_face_id))
# Create a frame for the checkbox and text labels
text_frame = ttk.Frame(match_frame)
text_frame.pack(side=tk.LEFT, padx=(0, 10))
# Configure match frame for grid layout
match_frame.columnconfigure(0, weight=0) # Checkbox column - fixed width
match_frame.columnconfigure(1, weight=1) # Text column - expandable
match_frame.columnconfigure(2, weight=0) # Image column - fixed width
# Checkbox without text
checkbox = ttk.Checkbutton(text_frame, variable=match_var)
checkbox.pack(side=tk.LEFT, padx=(0, 5))
checkbox = ttk.Checkbutton(match_frame, variable=match_var)
checkbox.grid(row=0, column=0, rowspan=2, sticky=(tk.W, tk.N), padx=(0, 5))
# Create labels for confidence and filename
confidence_label = ttk.Label(text_frame, text=f"{confidence_pct:.1f}% {confidence_desc}", font=("Arial", 9, "bold"))
confidence_label.pack(anchor=tk.W)
confidence_label = ttk.Label(match_frame, text=f"{confidence_pct:.1f}% {confidence_desc}", font=("Arial", 9, "bold"))
confidence_label.grid(row=0, column=1, sticky=tk.W, padx=(0, 10))
filename_label = ttk.Label(text_frame, text=f"📁 {filename}", font=("Arial", 8), foreground="gray")
filename_label.pack(anchor=tk.W)
filename_label = ttk.Label(match_frame, text=f"📁 {filename}", font=("Arial", 8), foreground="gray")
filename_label.grid(row=1, column=1, sticky=tk.W, padx=(0, 10))
# Face image (reusing auto-match image display)
try:
@ -2632,8 +2670,10 @@ class PhotoTagger:
face_crops.append(face_crop_path)
# Create canvas for face image (like in auto-match)
match_canvas = tk.Canvas(match_frame, width=80, height=80, bg='white')
match_canvas.pack(side=tk.LEFT, padx=(10, 0))
style = ttk.Style()
canvas_bg_color = style.lookup('TFrame', 'background') or '#d9d9d9'
match_canvas = tk.Canvas(match_frame, width=80, height=80, bg=canvas_bg_color, highlightthickness=0)
match_canvas.grid(row=0, column=2, rowspan=2, sticky=(tk.W, tk.N), padx=(10, 0))
# Load and display image (reusing auto-match image loading)
pil_image = Image.open(face_crop_path)