diff --git a/app.py b/app.py index a12103a..8a6f2f3 100644 --- a/app.py +++ b/app.py @@ -10,6 +10,7 @@ import threading class App: def __init__(self, master): self.master = master + self.master.title('Food Search') # Search food from database ----------------- @@ -22,52 +23,155 @@ class App: self.search_var = tk.StringVar() self.search_var.trace('w', self.search_callback) - self.search_entry = ttk.Entry(self.master, textvariable=self.search_var) - self.search_entry.grid(row=0, column=0, padx=10, pady=10, sticky="nsew") - - self.search_button = ttk.Button(self.master, text="Search", command=self.start_search) - self.search_button.grid(row=0, column=1, padx=10, pady=10, sticky="nsew") - self.results_frame = ttk.Frame(self.master) - self.results_frame.grid(row=1, column=0, padx=10, pady=10, sticky="nsew") + self.results_frame.grid(row=0, column=0, columnspan=2, rowspan=2, sticky="nsew") + self.results_frame.rowconfigure(0, weight=1) + self.results_frame.columnconfigure(0, weight=1) self.scrollbar = ttk.Scrollbar(self.results_frame) - self.scrollbar.grid(row=0, column=2, sticky="ns") + self.scrollbar.grid(row=0, column=2,rowspan=2, sticky="ns") - self.results_listbox = tk.Listbox(self.results_frame, yscrollcommand=self.scrollbar.set) - self.results_listbox.grid(row=0, column=0, columnspan=2, sticky="nsew") + self.results_listbox = tk.Listbox(self.results_frame, yscrollcommand=self.scrollbar.set,height=20,width=20,selectmode=tk.SINGLE) + self.results_listbox.grid(row=0, column=0, columnspan=2, padx=5, pady=5, sticky="nsew") self.scrollbar.config(command=self.results_listbox.yview) - self.selected_item = None + # Filter frame ----------------- + + self.filter_frame = ttk.LabelFrame(self.master, text="Filter") + self.filter_frame.grid(row=0, column=3, padx=10, pady=10, sticky="nsew") + + # Filter components ----------------- + + # Search + self.search_entry = ttk.Entry(self.filter_frame, textvariable=self.search_var) + self.search_entry.grid(row=0, column=3, padx=10, pady=10, sticky="nsew") + + self.search_button = ttk.Button(self.filter_frame, text="Search", command=self.start_search) + self.search_button.grid(row=0, column=4, padx=10, pady=10, sticky="nsew") + + # Filter + self.country_var = tk.StringVar() + self.country_dropdown = ttk.Combobox(self.filter_frame, textvariable=self.country_var, values=["Any" ,"Thai", "Japan", "US"]) + self.country_dropdown.grid(row=0, column=0, padx=10, pady=5, sticky="nsew") + + self.organic_var = tk.IntVar() + self.organic_checkbox = ttk.Checkbutton(self.filter_frame, text="Organic", variable=self.organic_var) + self.organic_checkbox.grid(row=1, column=0, padx=10, pady=5, sticky="nsew") + + self.plant_based_var = tk.IntVar() + self.plant_based_checkbox = ttk.Checkbutton(self.filter_frame, text="Plant-Based", variable=self.plant_based_var) + self.plant_based_checkbox.grid(row=2, column=0, padx=10, pady=5, sticky="nsew") + + self.beverages_var = tk.IntVar() + self.beverages_checkbox = ttk.Checkbutton(self.filter_frame, text="Beverages", variable=self.beverages_var) + self.beverages_checkbox.grid(row=3, column=0, padx=10, pady=5, sticky="nsew") + + self.snack_var = tk.IntVar() + self.snack_checkbox = ttk.Checkbutton(self.filter_frame, text="Snack", variable=self.snack_var) + self.snack_checkbox.grid(row=4, column=0, padx=10, pady=5, sticky="nsew") + + self.calories_var = tk.StringVar() + self.calories_entry = ttk.Entry(self.filter_frame, textvariable=self.calories_var) + self.calories_entry.grid(row=5, column=0, padx=10, pady=5, sticky="nsew") + + self.nutrient_var = tk.StringVar() + self.nutrient_dropdown = ttk.Combobox(self.filter_frame, textvariable=self.nutrient_var, values=["Protein", "Carbohydrates", "Fat", ""]) + self.nutrient_dropdown.grid(row=6, column=0, padx=10, pady=5, sticky="nsew") + + self.nutrient_value_var = tk.StringVar() + self.nutrient_value_entry = ttk.Entry(self.filter_frame, textvariable=self.nutrient_value_var) + self.nutrient_value_entry.grid(row=7, column=0, padx=10, pady=5, sticky="nsew") + + # Filter components (continued) ----------------- + + self.nutrient_operator_var = tk.StringVar() + self.nutrient_operator_dropdown = ttk.Combobox(self.filter_frame, textvariable=self.nutrient_operator_var, values=["<", ">", "="]) + self.nutrient_operator_dropdown.grid(row=8, column=0, padx=10, pady=5, sticky="nsew") # Image of food ----------------- 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) + self.image_frame.grid(row=2, column=0, padx=10, pady=10, sticky="nsew") + self.image_frame.grid_propagate(0) # 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") + self.process_frame = tk.Frame(root) + self.process_frame.grid(row=3, column=0, columnspan=1, padx=10, pady=10, sticky="ew") + s = ttk.Style() + s.configure("red.Horizontal.TProgressbar", foreground='red', background='red') + # Stackoverflow.com https://stackoverflow.com/questions/13510882/how-to-change-ttk-progressbar-color-in-python + self.progress_bar = ttk.Progressbar(self.process_frame, style="red.Horizontal.TProgressbar", orient="horizontal", + length=700, mode="indeterminate") + self.progress_bar.grid(row=0, column=0) # 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.default_image_label.grid(row=0, column=0, padx=10, pady=10, sticky="nsew") + self.default_image_label.pack(anchor='w', fill=tk.BOTH) - self.master.columnconfigure(0, weight=1) - self.master.columnconfigure(1, weight=0) - self.master.rowconfigure(1, weight=1) - self.master.rowconfigure(2, weight=1) + # Nutrient Frame - # Configure the window size and position - self.master.geometry("800x600") + self.nutrient_frame = ttk.LabelFrame(self.master, text="Nutrient") + self.nutrient_frame.grid(row=2, column=1, padx=10, pady=10, sticky="nsew") + + # Others Frame (Graph/Analyze) + + # * Configure the window size and position # self.master.attributes('-fullscreen', True) + # width= self.master.winfo_screenwidth() + # height= self.master.winfo_screenheight() + # self.master.geometry("%dx%d" % (width, height)) + + # LIST BOX selected FUNC + + def nutrient_labeler(self, product_name, frame): + count = 0 + selected_nutrients = [ + 'energy-kcal_100g', + 'proteins_100g', + 'carbohydrates_100g', + 'fat_100g', + 'fiber_100g', + 'sugars_100g', + 'saturated-fat_100g', + 'unsaturated-fat_100g' + 'sodium_100g', + 'vitamin-a_100g', + 'vitamin-c_100g', + 'calcium_100g', + 'iron_100g', + 'potassium_100g', + 'cholesterol_100g', + 'trans-fat_100g' + ] + + for widget in frame.winfo_children(): + widget.grid_forget() + for name, value in self.food_search.nutrient_show(product_name).items(): + if name in selected_nutrients: + count += 1 + if value is None: + value_text = "N/A" + else: + value_text = f"{value:.3f}" + ttk.Label(frame, text=f"{name}: {value_text}").grid(row=count, column=0) + + def on_item_selected(self, event): + widget = event.widget + selection = widget.curselection() + if selection: + index = selection[0] + value = widget.get(index) + self.selected_item = value + self.show_image(self.selected_item) + self.nutrient_labeler(self.selected_item, self.nutrient_frame) + + # SEARCH FUNC def search_callback(self, *args): pass @@ -90,15 +194,6 @@ class App: def clear_results(self): self.results_listbox.delete(0, tk.END) - def on_item_selected(self, event): - widget = event.widget - selection = widget.curselection() - if selection: - index = selection[0] - value = widget.get(index) - self.selected_item = value - self.show_image(self.selected_item) - # Image Showing Section ----------------- def show_image(self, item): @@ -121,7 +216,7 @@ class App: response = requests.get(image_url) img_data = response.content img = Image.open(io.BytesIO(img_data)) - img = img.resize((300, 300), Image.ANTIALIAS) + img = img.resize((300, 300), Image.LANCZOS) img_tk = ImageTk.PhotoImage(img) self.master.after(0, self.hide_progress_bar) @@ -152,7 +247,6 @@ class App: root = tk.Tk() app = App(root) -root.title('Food Search') app.results_listbox.bind('<>', app.on_item_selected) root.mainloop()