Загрузка данных


def load_products_cards(self):
        import os
        from PIL import Image, ImageTk
        
        # 1. Очищаем старое содержимое перед обновлением
        for widget in self.scrollable_frame.winfo_children():
            widget.destroy()

        # 2. Получаем список товаров
        products = self.db.get_all_products()
        
        # Папка, где лежат картинки
        images_dir = "images"
        if not os.path.exists(images_dir):
            os.makedirs(images_dir)
        
        for p in products:
            # Обработка данных
            try: discount = float(str(p.discount).replace('%', '').strip())
            except: discount = 0.0
            
            try: qty = float(str(p.quantity).strip())
            except: qty = 0.0

            # Цветовая схема
            bg_color = "#ADD8E6" if qty == 0 else ("#2E8B57" if discount > 10 else "#FFFFFF")
            fg_color = "white" if (discount > 10 and qty > 0) else "black"

            # Создаем контейнер карточки
            card_frame = tk.Frame(self.scrollable_frame, bg=bg_color, bd=2, relief=tk.SOLID)
            card_frame.pack(fill=tk.X, padx=10, pady=5, ipady=5)

            # --- ЛЕВАЯ ЧАСТЬ: ФОТО ---
            img_container = tk.Frame(card_frame, width=120, height=120, bg="#FFFFFF", bd=1, relief=tk.SOLID)
            img_container.pack(side=tk.LEFT, padx=15, pady=10)
            img_container.pack_propagate(False)

            # Логика определения пути
            photo_from_db = str(p.photo).strip() if p.photo else ""
            img_path = os.path.join(images_dir, photo_name := photo_from_db)
            
            # Если файла нет в БД или в папке — берем заглушку
            if not photo_name or not os.path.exists(img_path):
                img_path = os.path.join(images_dir, "picture.png")

            try:
                # Использование Pillow для загрузки
                pil_img = Image.open(img_path)
                # Изменяем размер под контейнер
                pil_img = pil_img.resize((110, 110), Image.Resampling.LANCZOS)
                img = ImageTk.PhotoImage(pil_img)
                
                img_lbl = tk.Label(img_container, image=img, bg="#FFFFFF")
                img_lbl.image = img # Сохраняем ссылку
                img_lbl.pack(fill=tk.BOTH, expand=True)
            except Exception as e:
                print(f"Ошибка загрузки фото {img_path}: {e}")
                tk.Label(img_container, text="Нет фото", bg="#FFFFFF").pack(fill=tk.BOTH, expand=True)

            # --- ЦЕНТРАЛЬНАЯ ЧАСТЬ: ИНФО ---
            info_frame = tk.Frame(card_frame, bg=bg_color)
            info_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=15, pady=10)

            tk.Label(info_frame, text=f"{p.category} | {p.name}", font=("Arial", 12, "bold"), bg=bg_color, fg=fg_color).pack(anchor=tk.W)
            tk.Label(info_frame, text=f"Описание: {p.description}", font=("Arial", 9), bg=bg_color, fg=fg_color, wraplength=400, justify=tk.LEFT).pack(anchor=tk.W)
            tk.Label(info_frame, text=f"Производитель: {p.manufacturer}", font=("Arial", 9), bg=bg_color, fg=fg_color).pack(anchor=tk.W)
            tk.Label(info_frame, text=f"Цена: {p.price} руб.", font=("Arial", 10, "bold"), bg=bg_color, fg=fg_color).pack(anchor=tk.W)
            tk.Label(info_frame, text=f"Наличие: {p.quantity} {p.unit}", font=("Arial", 9), bg=bg_color, fg=fg_color).pack(anchor=tk.W)

            # --- ПРАВАЯ ЧАСТЬ: СКИДКА ---
            discount_frame = tk.Frame(card_frame, bg=bg_color)
            discount_frame.pack(side=tk.RIGHT, padx=25, pady=10)
            tk.Label(discount_frame, text="Скидка", font=("Arial", 9), bg=bg_color, fg=fg_color).pack()
            tk.Label(discount_frame, text=f"{p.discount}%", font=("Arial", 14, "bold"), fg="red", bg=bg_color).pack()