Add last name search functionality in PhotoTagger GUI. Implement search and clear buttons for filtering people by last name, enhancing user experience. Update population logic to reflect filtered results and ensure smooth integration with existing data handling.

This commit is contained in:
tanyar09 2025-09-29 12:46:01 -04:00
parent 267519a034
commit 62bb0dc31f

View File

@ -3338,6 +3338,18 @@ class PhotoTagger:
people_frame = ttk.LabelFrame(main_frame, text="People", padding="10")
people_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 8))
people_frame.columnconfigure(0, weight=1)
# Search controls (Last Name)
last_name_search_var = tk.StringVar()
search_row = ttk.Frame(people_frame)
search_row.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 6))
search_entry = ttk.Entry(search_row, textvariable=last_name_search_var, width=20)
search_entry.pack(side=tk.LEFT)
search_btn = ttk.Button(search_row, text="Search", width=8)
search_btn.pack(side=tk.LEFT, padx=(6, 0))
clear_btn = ttk.Button(search_row, text="Clear", width=6)
clear_btn.pack(side=tk.LEFT, padx=(6, 0))
people_canvas = tk.Canvas(people_frame, bg='white')
people_scrollbar = ttk.Scrollbar(people_frame, orient="vertical", command=people_canvas.yview)
people_list_inner = ttk.Frame(people_canvas)
@ -3349,9 +3361,9 @@ class PhotoTagger:
lambda e: people_canvas.configure(scrollregion=people_canvas.bbox("all"))
)
people_canvas.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
people_scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
people_frame.rowconfigure(0, weight=1)
people_canvas.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
people_scrollbar.grid(row=1, column=1, sticky=(tk.N, tk.S))
people_frame.rowconfigure(1, weight=1)
# Right panel: Faces for selected person
faces_frame = ttk.LabelFrame(main_frame, text="Faces", padding="10")
@ -3399,6 +3411,7 @@ class PhotoTagger:
# Load people from DB with counts
people_data = [] # list of dicts: {id, name, count, first_name, last_name}
people_filtered = None # filtered subset based on last name search
def load_people():
nonlocal people_data
@ -3445,6 +3458,34 @@ class PhotoTagger:
'date_of_birth': date_of_birth or "",
'count': count
})
# Re-apply filter (if any) after loading
try:
apply_last_name_filter()
except Exception:
pass
# Wire up search controls now that helper functions exist
try:
search_btn.config(command=lambda: apply_last_name_filter())
clear_btn.config(command=lambda: clear_last_name_filter())
search_entry.bind('<Return>', lambda e: apply_last_name_filter())
except Exception:
pass
def apply_last_name_filter():
nonlocal people_filtered
query = last_name_search_var.get().strip().lower()
if query:
people_filtered = [p for p in people_data if p.get('last_name', '').lower().find(query) != -1]
else:
people_filtered = None
populate_people_list()
def clear_last_name_filter():
nonlocal people_filtered
last_name_search_var.set("")
people_filtered = None
populate_people_list()
def clear_faces_panel():
for w in faces_inner.winfo_children():
@ -3618,7 +3659,12 @@ class PhotoTagger:
def populate_people_list():
for w in people_list_inner.winfo_children():
w.destroy()
for idx, person in enumerate(people_data):
source = people_filtered if people_filtered is not None else people_data
if not source:
empty_label = ttk.Label(people_list_inner, text="No people match filter", foreground="gray")
empty_label.grid(row=0, column=0, sticky=tk.W, pady=4)
return
for idx, person in enumerate(source):
row = ttk.Frame(people_list_inner)
row.grid(row=idx, column=0, sticky=(tk.W, tk.E), pady=4)
# Freeze per-row values to avoid late-binding issues