mirror of
https://github.com/Sosokker/Packaged-Food-Explorer.git
synced 2025-12-19 05:04:06 +01:00
change lay/out, add progress bar/more responsive
This commit is contained in:
parent
fb62600048
commit
c6c602f78f
97
app.py
97
app.py
@ -1,15 +1,18 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
|
from tkinter import ttk
|
||||||
import requests
|
import requests
|
||||||
import io
|
import io
|
||||||
from Essential.prepare_db import prepare_db
|
|
||||||
from PIL import Image, ImageTk
|
from PIL import Image, ImageTk
|
||||||
|
from Essential.prepare_db import prepare_db
|
||||||
from Essential.FoodSearch import FoodSearch
|
from Essential.FoodSearch import FoodSearch
|
||||||
|
import threading
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
def __init__(self, master):
|
def __init__(self, master):
|
||||||
self.master = master
|
self.master = master
|
||||||
|
|
||||||
|
# Search food from database -----------------
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.food_search = FoodSearch()
|
self.food_search = FoodSearch()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
@ -19,39 +22,65 @@ class App:
|
|||||||
self.search_var = tk.StringVar()
|
self.search_var = tk.StringVar()
|
||||||
self.search_var.trace('w', self.search_callback)
|
self.search_var.trace('w', self.search_callback)
|
||||||
|
|
||||||
self.search_entry = tk.Entry(self.master, textvariable=self.search_var)
|
self.search_entry = ttk.Entry(self.master, textvariable=self.search_var)
|
||||||
self.search_entry.grid(row=0, column=0, padx=10, pady=10)
|
self.search_entry.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
|
||||||
|
|
||||||
self.search_button = tk.Button(self.master, text="Search", command=self.search)
|
self.search_button = ttk.Button(self.master, text="Search", command=self.start_search)
|
||||||
self.search_button.grid(row=1, column=0, padx=10, pady=10)
|
self.search_button.grid(row=0, column=1, padx=10, pady=10, sticky="nsew")
|
||||||
|
|
||||||
self.results_frame = tk.Frame(self.master)
|
self.results_frame = ttk.Frame(self.master)
|
||||||
self.results_frame.grid(row=2, column=0, padx=10, pady=10, sticky="nsew")
|
self.results_frame.grid(row=1, column=0, padx=10, pady=10, sticky="nsew")
|
||||||
|
|
||||||
self.scrollbar = tk.Scrollbar(self.results_frame)
|
self.scrollbar = ttk.Scrollbar(self.results_frame)
|
||||||
self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
self.scrollbar.grid(row=0, column=2, sticky="ns")
|
||||||
|
|
||||||
self.results_listbox = tk.Listbox(self.results_frame, yscrollcommand=self.scrollbar.set)
|
self.results_listbox = tk.Listbox(self.results_frame, yscrollcommand=self.scrollbar.set)
|
||||||
self.results_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
self.results_listbox.grid(row=0, column=0, columnspan=2, sticky="nsew")
|
||||||
|
|
||||||
self.scrollbar.config(command=self.results_listbox.yview)
|
self.scrollbar.config(command=self.results_listbox.yview)
|
||||||
|
|
||||||
self.selected_item = None
|
self.selected_item = None
|
||||||
|
|
||||||
self.image_frame = tk.Frame(self.master, bg='white')
|
# Image of food -----------------
|
||||||
self.image_frame.grid(row=0, column=2, rowspan=3, padx=10, pady=10, sticky="nsew")
|
|
||||||
|
self.image_frame = ttk.Frame(self.master, borderwidth=2, relief=tk.SUNKEN)
|
||||||
|
self.image_frame.grid(row=2, column=0, padx=10, pady=10, sticky="nsew", columnspan=2)
|
||||||
|
self.image_frame.grid_rowconfigure(0, weight=1)
|
||||||
|
self.image_frame.grid_columnconfigure(0, weight=1)
|
||||||
|
|
||||||
|
# Progress bar -----------------
|
||||||
|
|
||||||
|
self.progress_bar = ttk.Progressbar(self.master, mode='indeterminate')
|
||||||
|
self.progress_bar.grid(row=3, column=0, columnspan=2, padx=10, pady=10, sticky="we")
|
||||||
|
|
||||||
|
# Default image (Not Found) -----------------
|
||||||
|
|
||||||
|
self.default_image_path = 'resources/notfound.png' # Replace with the correct path to your default image
|
||||||
|
self.default_image = ImageTk.PhotoImage(Image.open(self.default_image_path))
|
||||||
|
self.default_image_label = ttk.Label(self.image_frame, image=self.default_image)
|
||||||
|
self.default_image_label.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
|
||||||
|
|
||||||
self.master.columnconfigure(0, weight=1)
|
self.master.columnconfigure(0, weight=1)
|
||||||
self.master.columnconfigure(1, weight=0)
|
self.master.columnconfigure(1, weight=0)
|
||||||
self.master.columnconfigure(2, weight=1)
|
self.master.rowconfigure(1, weight=1)
|
||||||
self.master.rowconfigure(2, weight=1)
|
self.master.rowconfigure(2, weight=1)
|
||||||
|
|
||||||
|
# Configure the window size and position
|
||||||
|
self.master.geometry("800x600")
|
||||||
|
# self.master.attributes('-fullscreen', True)
|
||||||
|
|
||||||
def search_callback(self, *args):
|
def search_callback(self, *args):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def start_search(self):
|
||||||
|
# Create a new thread to execute the search function
|
||||||
|
search_thread = threading.Thread(target=self.search)
|
||||||
|
search_thread.start()
|
||||||
|
|
||||||
def search(self):
|
def search(self):
|
||||||
results = self.food_search.search(self.search_var.get())
|
results = self.food_search.search(self.search_var.get())
|
||||||
self.update_results(results)
|
# Call the update_results function on the main thread to update the GUI
|
||||||
|
self.master.after(0, self.update_results, results)
|
||||||
|
|
||||||
def update_results(self, results):
|
def update_results(self, results):
|
||||||
self.results_listbox.delete(0, tk.END)
|
self.results_listbox.delete(0, tk.END)
|
||||||
@ -70,6 +99,8 @@ class App:
|
|||||||
self.selected_item = value
|
self.selected_item = value
|
||||||
self.show_image(self.selected_item)
|
self.show_image(self.selected_item)
|
||||||
|
|
||||||
|
# Image Showing Section -----------------
|
||||||
|
|
||||||
def show_image(self, item):
|
def show_image(self, item):
|
||||||
image_url = None
|
image_url = None
|
||||||
for result in self.food_search.search(self.search_var.get()):
|
for result in self.food_search.search(self.search_var.get()):
|
||||||
@ -78,25 +109,49 @@ class App:
|
|||||||
break
|
break
|
||||||
|
|
||||||
if not image_url:
|
if not image_url:
|
||||||
|
self.display_default_image()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
threading.Thread(target=self.fetch_and_display_image, args=(image_url,)).start()
|
||||||
|
|
||||||
|
def fetch_and_display_image(self, image_url):
|
||||||
|
self.master.after(0, self.show_progress_bar)
|
||||||
|
|
||||||
|
# Fetch the image
|
||||||
response = requests.get(image_url)
|
response = requests.get(image_url)
|
||||||
img_data = response.content
|
img_data = response.content
|
||||||
img = Image.open(io.BytesIO(img_data))
|
img = Image.open(io.BytesIO(img_data))
|
||||||
img = img.resize((300, 300), Image.ANTIALIAS)
|
img = img.resize((300, 300), Image.ANTIALIAS)
|
||||||
img_tk = ImageTk.PhotoImage(img)
|
img_tk = ImageTk.PhotoImage(img)
|
||||||
|
|
||||||
# remove old image label widget
|
self.master.after(0, self.hide_progress_bar)
|
||||||
|
|
||||||
|
self.master.after(0, self.update_image_label, img_tk)
|
||||||
|
|
||||||
|
def show_progress_bar(self):
|
||||||
|
self.progress_bar.start()
|
||||||
|
self.progress_bar.grid(row=3, column=1)
|
||||||
|
|
||||||
|
def hide_progress_bar(self):
|
||||||
|
self.progress_bar.stop()
|
||||||
|
self.progress_bar.pack_forget()
|
||||||
|
|
||||||
|
def display_default_image(self):
|
||||||
|
self.master.after(0, self.update_image_label, self.default_image)
|
||||||
|
|
||||||
|
def update_image_label(self, image):
|
||||||
|
# Remove old image label widget
|
||||||
for widget in self.image_frame.winfo_children():
|
for widget in self.image_frame.winfo_children():
|
||||||
widget.destroy()
|
widget.destroy()
|
||||||
|
|
||||||
self.image_frame.configure(bg='white')
|
image_label = tk.Label(self.image_frame, image=image)
|
||||||
label = tk.Label(self.image_frame, image=img_tk, bg='white')
|
image_label.image = image
|
||||||
label.image = img_tk
|
image_label.grid(row=0, column=2)
|
||||||
label.pack(fill=tk.BOTH, expand=True)
|
|
||||||
|
# ---------------------
|
||||||
|
|
||||||
root = tk.Tk()
|
root = tk.Tk()
|
||||||
app = App(root)
|
app = App(root)
|
||||||
root.geometry("800x400")
|
|
||||||
root.title('Food Search')
|
root.title('Food Search')
|
||||||
app.results_listbox.bind('<<ListboxSelect>>', app.on_item_selected)
|
app.results_listbox.bind('<<ListboxSelect>>', app.on_item_selected)
|
||||||
|
|
||||||
|
|||||||
BIN
resources/loading.gif
Normal file
BIN
resources/loading.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
BIN
resources/notfound.png
Normal file
BIN
resources/notfound.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Loading…
Reference in New Issue
Block a user