From 07620031415e76b5adc28f28d11fdc64ace4f0aa Mon Sep 17 00:00:00 2001 From: sosokker Date: Tue, 2 May 2023 14:41:37 +0700 Subject: [PATCH] change to MVC pattern --- app/controller.py | 26 +++++++++++++++ app/model.py | 13 ++++++++ app/view.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++ main.py | 11 +++++++ 4 files changed, 131 insertions(+) create mode 100644 app/controller.py create mode 100644 app/model.py create mode 100644 app/view.py create mode 100644 main.py diff --git a/app/controller.py b/app/controller.py new file mode 100644 index 0000000..797d3b9 --- /dev/null +++ b/app/controller.py @@ -0,0 +1,26 @@ +# controller.py + +import tkinter as tk +from model import FoodSearch +from view import AppView + +class AppController: + def __init__(self, master): + self.master = master + self.food_search = FoodSearch('food_data.db') + self.view = AppView(master, self) + + def search(self, query): + results = self.food_search.search(query) + self.view.update_results(results) + + def clear_results(self): + self.view.clear_results() + + def on_item_selected(self, event): + widget = event.widget + selection = widget.curselection() + if selection: + index = selection[0] + value = widget.get(index) + self.view.show_image(value) diff --git a/app/model.py b/app/model.py new file mode 100644 index 0000000..25ad312 --- /dev/null +++ b/app/model.py @@ -0,0 +1,13 @@ +import sqlite3 + +class FoodSearch: + def __init__(self, db_path): + self.conn = sqlite3.connect(db_path) + self.cursor = self.conn.cursor() + + def search(self, user_input) -> list: + query = f"SELECT * FROM food_data WHERE product_name LIKE '%{user_input}%'" + self.cursor.execute(query) + results = self.cursor.fetchall() + + return results \ No newline at end of file diff --git a/app/view.py b/app/view.py new file mode 100644 index 0000000..58181c9 --- /dev/null +++ b/app/view.py @@ -0,0 +1,81 @@ +import tkinter as tk +import requests +import io +from PIL import Image, ImageTk + +class AppView: + def __init__(self, master, controller): + self.master = master + self.controller = controller + + self.search_var = tk.StringVar() + self.search_var.trace('w', self.search_callback) + + self.search_entry = tk.Entry(self.master, textvariable=self.search_var) + self.search_entry.grid(row=0, column=0, padx=10, pady=10) + + self.search_button = tk.Button(self.master, text="Search", command=self.search_callback) + self.search_button.grid(row=1, column=0, padx=10, pady=10) + + self.results_frame = tk.Frame(self.master) + self.results_frame.grid(row=2, column=0, padx=10, pady=10, sticky="nsew") + + self.scrollbar = tk.Scrollbar(self.results_frame) + self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) + + 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.scrollbar.config(command=self.results_listbox.yview) + + self.selected_item = None + + self.image_frame = tk.Frame(self.master, bg='white') + self.image_frame.grid(row=0, column=2, rowspan=3, padx=10, pady=10, sticky="nsew") + + self.master.columnconfigure(0, weight=1) + self.master.columnconfigure(1, weight=0) + self.master.columnconfigure(2, weight=1) + self.master.rowconfigure(2, weight=1) + + self.results_listbox.bind('<>', self.on_item_selected) + + def search_callback(self, *args): + query = self.search_var.get() + self.controller.search(query) + + def update_results(self, results): + self.results_listbox.delete(0, tk.END) + for result in results: + self.results_listbox.insert(tk.END, result[1]) + + def clear_results(self): + self.results_listbox.delete(0, tk.END) + + def on_item_selected(self, event): + self.controller.on_item_selected(event) + + def show_image(self, item): + image_url = None + for result in self.food_search.search(self.search_var.get()): + if result[1] == item: + image_url = result[13] + break + + if not image_url: + return + + response = requests.get(image_url) + img_data = response.content + img = Image.open(io.BytesIO(img_data)) + img = img.resize((300, 300), Image.ANTIALIAS) + img_tk = ImageTk.PhotoImage(img) + + # remove old image label widget + for widget in self.image_frame.winfo_children(): + widget.destroy() + + self.image_frame.configure(bg='white') + label = tk.Label(self.image_frame, image=img_tk, bg='white') + label.image = img_tk + label.pack(fill=tk.BOTH, expand=True) \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..ec97173 --- /dev/null +++ b/main.py @@ -0,0 +1,11 @@ +import tkinter as tk +from app.controller import Controller +from app.model import Model +from app.view import View + +if __name__ == '__main__': + root = tk.Tk() + model = Model() + view = View(root) + controller = Controller(model, view) + root.mainloop()