Tambahan Sub Menu Lainnya Pada "Menu Data Bahan Makanan"

 TAMBAHAN SUB MENU LAINNYA PADA "MENU DATA BAHAN MAKANAN"


Kira-kira Konten apa lagi yang perlu kita tambahkan pada "Menu Data Bahan Makanan" ini sebagai tambahan sub menu di bawah menu ini.

Kalau kita mau bikin Menu Data Bahan Makanan ini jadi benar-benar kaya fitur dan praktis, saya usulkan beberapa sub menu tambahan supaya fungsinya lebih lengkap, tidak cuma lihat daftar & cari gizi saja.

Berikut idenya:


📋 Usulan Sub Menu Tambahan

  1. 📦 Kelompokkan Bahan Makanan

    • Fungsi: Menampilkan bahan makanan berdasarkan kategori, misalnya:
      • Sumber Karbohidrat
      • Sumber Protein Hewani
      • Sumber Protein Nabati
      • Sayur-sayuran
      • Buah-buahan
    • Manfaat: Memudahkan pencarian bahan sesuai jenisnya.
  2. 📊 Analisis Kombinasi Bahan

    • Fungsi: Pilih beberapa bahan → aplikasi menghitung total gizi (Kalori, Protein, Lemak, Karbohidrat, Vitamin) gabungan.
    • Manfaat: Berguna untuk merencanakan menu harian.
  3. 📈 Ranking Bahan Berdasarkan Gizi Tertentu

    • Fungsi: Urutkan bahan berdasarkan kandungan tertinggi untuk gizi tertentu (misal: protein terbanyak).
    • Manfaat: Membantu memilih bahan dengan kualitas gizi terbaik.
  4. 📝 Edit & Perbarui Data Bahan

    • Fungsi: Mengubah data gizi bahan yang sudah ada (misal: memperbaiki kesalahan atau update data).
    • Manfaat: Database tetap akurat dan up to date.
  5. 🗑 Hapus Semua Data Bahan

    • Fungsi: Menghapus semua data di database sekaligus (dengan konfirmasi keamanan).
    • Manfaat: Reset database untuk kebutuhan baru.
  6. 📤 Ekspor Data Bahan ke CSV

    • Fungsi: Menyimpan semua data bahan ke file CSV agar bisa dibuka di Excel.
    • Manfaat: Memudahkan backup dan berbagi data.

Kalau menurut saya, fitur #2 (Analisis Kombinasi Bahan) dan fitur #3 (Ranking Bahan) itu akan bikin aplikasi ini terasa jauh lebih pintar, karena ini sudah masuk ke level "decision support" buat pengguna.

Kalau kamu mau, saya bisa langsung susun urutan Menu Data Bahan Makanan yang sudah berisi semua sub menu ini dan sambil buatkan kerangka file-filenya.
Begitu kamu eksekusi, semua tombol akan muncul meskipun isinya nanti kita isi bertahap.

Mau saya susun strukturnya sekarang?


Isi Menu "Data Bahan Makanan"

(Konten Sub Menu "Kelompok Bahan Makanan")

3. Sub Menu  “Kelompok Bahan Makanan"

Sekarang kita masuk ke Menu Data Bahan Makanan, kita lanjut membuat konten Sub Menu  "Kelompok Bahan Makanan"

Bagus — kita mulai dari Sub Menu "Kelompok Bahan Makanan".
Saya buatkan file lengkap sub_menu_kelompokkan_bahan.py yang:

  • Menambahkan kolom kategori pada tabel bahan_makanan bila belum ada (safe ALTER TABLE).
  • Menampilkan daftar bahan beserta kategorinya (Treeview).
  • Bisa filter berdasarkan kategori.
  • Bisa assign category ke satu / banyak item sekaligus (popup pilih category atau tulis baru).
  • Bisa remove category (mengosongkan kategori pada item terpilih).
  • Tombol Segarkan dan Kembali.

Salin-tempel isi berikut ke file sub_menu_kelompokkan_bahan.py di folder project kamu.

# sub_menu_kelompokkan_bahan.py
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import sqlite3
import os

DATABASE_PATH = "/storage/emulated/0/AppJadi/SmartNutriChefAI/Database/data_bahan_makanan.db"

# ======== Helper DB ========
def ensure_db_and_kategori():
    os.makedirs(os.path.dirname(DATABASE_PATH), exist_ok=True)
    conn = sqlite3.connect(DATABASE_PATH)
    c = conn.cursor()
    # buat tabel dasar bila belum ada
    c.execute("""
        CREATE TABLE IF NOT EXISTS bahan_makanan (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            nama TEXT NOT NULL,
            kalori REAL,
            protein REAL,
            lemak REAL,
            karbohidrat REAL,
            vitamin TEXT
        )
    """)
    # periksa kolom kategori, tambahkan jika belum ada
    c.execute("PRAGMA table_info(bahan_makanan)")
    cols = [row[1] for row in c.fetchall()]  # row: (cid,name,type,...)
    if "kategori" not in cols:
        try:
            c.execute("ALTER TABLE bahan_makanan ADD COLUMN kategori TEXT DEFAULT 'Uncategorized'")
        except Exception:
            # safe fallback: jika gagal, abaikan (biasanya tidak terjadi)
            pass
    conn.commit()
    conn.close()

def get_categories():
    conn = sqlite3.connect(DATABASE_PATH)
    c = conn.cursor()
    c.execute("SELECT DISTINCT kategori FROM bahan_makanan WHERE kategori IS NOT NULL AND kategori != '' ORDER BY kategori COLLATE NOCASE")
    rows = c.fetchall()
    conn.close()
    cats = [r[0] for r in rows if r[0] is not None]
    # letakkan opsi Semua di depan
    if "Uncategorized" in cats:
        # biarkan "Uncategorized" tetap, tapi taruh setelah "Semua"
        cats = [c for c in cats if c != "Uncategorized"]
        cats.insert(0, "Uncategorized")
    cats.insert(0, "Semua")
    return cats

def get_items_by_category(kategori=None):
    conn = sqlite3.connect(DATABASE_PATH)
    c = conn.cursor()
    if kategori and kategori != "Semua":
        c.execute("""
            SELECT id, nama, IFNULL(kategori, ''), kalori, protein, lemak, karbohidrat, IFNULL(vitamin,'')
            FROM bahan_makanan WHERE kategori = ? ORDER BY nama COLLATE NOCASE
        """, (kategori,))
    else:
        c.execute("""
            SELECT id, nama, IFNULL(kategori, ''), kalori, protein, lemak, karbohidrat, IFNULL(vitamin,'')
            FROM bahan_makanan ORDER BY nama COLLATE NOCASE
        """)
    rows = c.fetchall()
    conn.close()
    return rows

def update_category_for_ids(ids, kategori):
    if not ids:
        return
    conn = sqlite3.connect(DATABASE_PATH)
    c = conn.cursor()
    for _id in ids:
        c.execute("UPDATE bahan_makanan SET kategori = ? WHERE id = ?", (kategori, _id))
    conn.commit()
    conn.close()

def remove_category_for_ids(ids):
    if not ids:
        return
    conn = sqlite3.connect(DATABASE_PATH)
    c = conn.cursor()
    for _id in ids:
        c.execute("UPDATE bahan_makanan SET kategori = '' WHERE id = ?", (_id,))
    conn.commit()
    conn.close()

# ======== UI ========
def show_sub_menu_kelompokkan_bahan(root_frame):
    from menu_data_bahan_makanan import show_menu_data_bahan_makanan  # import lokal untuk hindari circular import

    ensure_db_and_kategori()

    # clear frame
    for w in root_frame.winfo_children():
        w.destroy()

    # Judul (sub menu — gunakan background biru terang & teks hijau sesuai permintaan sebelumnya)
    header = tk.Label(root_frame, text="Kelompok Bahan Makanan",
                      font=("Arial", 18, "bold"),
                      bg="light blue", fg="green", pady=8)
    header.pack(fill="x")

    # Filter frame (pilih kategori)
    filter_frame = tk.Frame(root_frame)
    filter_frame.pack(fill="x", pady=8, padx=8)

    tk.Label(filter_frame, text="Filter kategori:", font=("Arial", 12)).pack(side="left", padx=(0,6))
    kategori_var = tk.StringVar()
    cb_kategori = ttk.Combobox(filter_frame, textvariable=kategori_var, state="readonly", width=25)
    cb_kategori.pack(side="left")

    def refresh_categories():
        cats = get_categories()
        cb_kategori['values'] = cats
        if cats:
            cb_kategori.set(cats[0])
    refresh_categories()

    def aksi_filter():
        load_table(cb_kategori.get())

    tk.Button(filter_frame, text="Tampilkan", bg="#4CAF50", fg="white", command=aksi_filter).pack(side="left", padx=6)
    tk.Button(filter_frame, text="Segarkan Kategori", command=refresh_categories).pack(side="left", padx=6)

    # Table frame with scrollbars
    table_frame = tk.Frame(root_frame)
    table_frame.pack(fill="both", expand=True, padx=8, pady=(0,8))

    tree_cols = ("ID", "Nama", "Kategori", "Kalori\n(kkal)", "Protein\n(g)", "Lemak\n(g)", "Karbohidrat\n(g)", "Vitamin")
    tree = ttk.Treeview(table_frame, columns=tree_cols, show="headings", selectmode="extended")
    # headings
    for col in tree_cols:
        tree.heading(col, text=col)
    # columns width & alignment
    tree.column("ID", width=50, anchor="center")
    tree.column("Nama", width=220, anchor="w")
    tree.column("Kategori", width=140, anchor="center")
    tree.column("Kalori\n(kkal)", width=100, anchor="center")
    tree.column("Protein\n(g)", width=100, anchor="center")
    tree.column("Lemak\n(g)", width=100, anchor="center")
    tree.column("Karbohidrat\n(g)", width=120, anchor="center")
    tree.column("Vitamin", width=140, anchor="center")

    # scrollbars
    vsb = ttk.Scrollbar(table_frame, orient="vertical", command=tree.yview)
    hsb = ttk.Scrollbar(table_frame, orient="horizontal", command=tree.xview)
    tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)

    vsb.pack(side="right", fill="y")
    hsb.pack(side="bottom", fill="x")
    tree.pack(fill="both", expand=True, side="left")

    # fungsi load data ke tabel
    def load_table(kategori=None):
        tree.delete(*tree.get_children())
        rows = get_items_by_category(kategori)
        if not rows:
            # tampil pesan kecil di tabel (insert dummy row) atau biarkan kosong
            return
        for r in rows:
            # r = (id, nama, kategori, kalori, protein, lemak, karbohidrat, vitamin)
            tree.insert("", "end", values=r)

    load_table()  # load all awal

    # Buttons bawah tabel (assign / remove / refresh)
    btns_frame = tk.Frame(root_frame)
    btns_frame.pack(fill="x", pady=6)

    def open_assign_popup():
        sel = tree.selection()
        if not sel:
            messagebox.showwarning("Peringatan", "Pilih paling sedikit satu bahan untuk diberi kategori.")
            return
        # ambil daftar kategori saat ini + opsi buat baru
        cats = get_categories()
        # popup
        popup = tk.Toplevel(root_frame)
        popup.title("Assign Category")
        popup.geometry("360x160")
        tk.Label(popup, text="Pilih kategori (atau tulis kategori baru):").pack(pady=6)
        combo_var = tk.StringVar()
        combo = ttk.Combobox(popup, textvariable=combo_var, values=cats, state="normal", width=30)
        combo.pack(pady=4)
        combo.set(cats[0] if cats else "")
        entry_new = tk.Entry(popup, width=30)
        entry_new.pack(pady=4)
        entry_new.insert(0, "")  # kosong default

        def apply_category():
            chosen = entry_new.get().strip() or combo_var.get().strip()
            if not chosen:
                messagebox.showwarning("Peringatan", "Kategori tidak boleh kosong.")
                return
            ids = []
            for it in sel:
                vals = tree.item(it, "values")
                try:
                    ids.append(int(vals[0]))
                except Exception:
                    pass
            if not ids:
                messagebox.showerror("Error", "Gagal membaca data yang dipilih.")
                popup.destroy()
                return
            update_category_for_ids(ids, chosen)
            popup.destroy()
            refresh_categories()
            load_table(cb_kategori.get())

        tk.Button(popup, text="Terapkan", bg="#4CAF50", fg="white", command=apply_category).pack(pady=8)

    def remove_category_selected():
        sel = tree.selection()
        if not sel:
            messagebox.showwarning("Peringatan", "Pilih paling sedikit satu bahan untuk dihapus kategorinya.")
            return
        if not messagebox.askyesno("Konfirmasi", "Kosongkan kategori untuk item yang terpilih?"):
            return
        ids = []
        for it in sel:
            vals = tree.item(it, "values")
            try:
                ids.append(int(vals[0]))
            except Exception:
                pass
        remove_category_for_ids(ids)
        refresh_categories()
        load_table(cb_kategori.get())

    def segarkan_semua():
        refresh_categories()
        load_table(cb_kategori.get())

    tk.Button(btns_frame, text="Assign Category ke Terpilih", bg="#1976D2", fg="white", command=open_assign_popup).pack(side="left", padx=6)
    tk.Button(btns_frame, text="Hapus Kategori dari Terpilih", bg="#D32F2F", fg="white", command=remove_category_selected).pack(side="left", padx=6)
    tk.Button(btns_frame, text="Segarkan", bg="#4CAF50", fg="white", command=segarkan_semua).pack(side="left", padx=6)

    # Tombol Kembali fixed di bawah
    footer = tk.Frame(root_frame)
    footer.pack(fill="x", side="bottom")
    tk.Button(footer, text="Kembali ke Menu Data Bahan Makanan", font=("Arial", 14),
              bg="gray", fg="white", width=35, height=2,
              command=lambda: show_menu_data_bahan_makanan(root_frame)).pack(pady=6)

    # Binding double-click: edit category cepat
    def on_double_click(event):
        item = tree.identify_row(event.y)
        if not item:
            return
        vals = tree.item(item, "values")
        try:
            item_id = int(vals[0])
        except Exception:
            return
        # minta kategori baru
        new_cat = simpledialog.askstring("Edit Kategori", f"Masukkan kategori untuk '{vals[1]}' (kosong = hapus):")
        if new_cat is None:
            return
        if new_cat.strip() == "":
            remove_category_for_ids([item_id])
        else:
            update_category_for_ids([item_id], new_cat.strip())
        segarkan_semua()

    tree.bind("<Double-1>", on_double_click)

Kalau kamu mau, langkah selanjutnya saya bisa:

  • Tambahkan validasi & hint (mis. warna baris bila kategori=='' → tampilkan Uncategorized dengan warna khusus).
  • Buat export kategori ke CSV.
  • Buat tampilan pra-definisi kategori (mis. kelompok: Karbohidrat / Protein Hewani / Sayuran / Buah / Lemak) agar pengguna bisa memilih dari daftar kategori standar.

Mau lanjut pakai salah satu tambahan itu sekarang?


Bagaimana dengan perubahan kode pada isi file "menu_data_bahan_makanan.py"

Untuk menambahkan Sub Menu "Kelompok Bahan Makanan" ke dalam menu_data_bahan_makanan.py, kamu hanya perlu:

  1. Menambahkan tombol atau item menu yang memanggil fungsi show_sub_menu_kelompokkan_bahan() dari file sub_menu_kelompokkan_bahan.py.
  2. Pastikan import dilakukan secara lokal (di dalam fungsi) supaya tidak terjadi circular import.

Contoh update menu_data_bahan_makanan.py:

# menu_data_bahan_makanan.py
import tkinter as tk

def show_menu_data_bahan_makanan(root_frame):
    # Bersihkan frame
    for widget in root_frame.winfo_children():
        widget.destroy()

    header = tk.Label(root_frame, text="Menu Data Bahan Makanan",
                      font=("Arial", 18, "bold"),
                      bg="light blue", fg="green", pady=8)
    header.pack(fill="x")

    menu_frame = tk.Frame(root_frame)
    menu_frame.pack(fill="both", expand=True, pady=20)

    # Tombol: Lihat Daftar Bahan
    tk.Button(menu_frame, text="Lihat Daftar Bahan", font=("Arial", 14),
              width=35, height=2,
              command=lambda: __import__('sub_menu_lihat_daftar_bahan').show_sub_menu_lihat_daftar_bahan(root_frame)).pack(pady=6)

    # Tombol: Cari Bahan Berdasarkan Gizi
    tk.Button(menu_frame, text="Cari Bahan Berdasarkan Gizi", font=("Arial", 14),
              width=35, height=2,
              command=lambda: __import__('sub_menu_cari_bahan_gizi').show_sub_menu_cari_bahan_gizi(root_frame)).pack(pady=6)

    # Tombol: Kelompok Bahan Makanan (baru ditambahkan)
    tk.Button(menu_frame, text="Kelompok Bahan Makanan", font=("Arial", 14),
              width=35, height=2,
              command=lambda: __import__('sub_menu_kelompokkan_bahan').show_sub_menu_kelompokkan_bahan(root_frame)).pack(pady=6)

    # Tombol kembali ke menu utama
    tk.Button(menu_frame, text="Kembali ke Menu Utama", font=("Arial", 14),
              width=35, height=2,
              command=lambda: __import__('menu_utama').show_menu_utama(root_frame)).pack(pady=6)

Perubahan penting:

  • Saya pakai __import__('nama_file') untuk menghindari import di awal file, sehingga modul hanya di-load ketika dibutuhkan → ini mencegah masalah circular import.
  • Tambahan tombol Kelompok Bahan Makanan memanggil show_sub_menu_kelompokkan_bahan() dari file yang tadi kita buat.

Kalau mau, saya bisa langsung buatkan versi lengkap menu_data_bahan_makanan.py yang sudah sinkron dengan semua sub menu yang kita rancang, termasuk Cari Bahan Berdasarkan Gizi dan sub menu lainnya.
Mau saya buatkan yang versi lengkap itu?


Tolong kamu rapikan dan persingkat kode isi file "menu_data_bahan_makanan.py" berikut ini:

# Menu Data Bahan Makanan

import tkinter as tk

from DataBahanMakanan.sub_menu_lihat_daftar_bahan import show_sub_menu_lihat_daftar_bahan

from DataBahanMakanan.sub_menu_cari_data_gizi import show_sub_menu_cari_data_gizi

from DataBahanMakanan.sub_menu_kelompokkan_bahan import show_sub_menu_kelompokkan_bahan


def show_menu_data_bahan_makanan(root_frame):

    # Hapus semua widget yang ada

    for widget in root_frame.winfo_children():

        widget.destroy()


    # Judul menu

    tk.Label(root_frame, text="Data Bahan Makanan", font=("Arial", 18, "bold"),

             bg="green", fg="white", pady=10).pack(pady=20)


    # Tombol ke sub menu "Lihat Daftar Bahan"

    tk.Button(root_frame, text="Lihat Daftar Bahan", font=("Arial", 14),

              bg="#4CAF50", fg="white", width=25, height=2,

              command=lambda: show_sub_menu_lihat_daftar_bahan(root_frame)).pack(pady=10)

              

    tk.Button(root_frame, text="Cari Data Gizi", font=("Arial", 14),

              bg="#4CAF50", fg="white", width=25, height=2,

              command=lambda: show_sub_menu_cari_data_gizi(root_frame)).pack(pady=10)        

                 

    tk.Button(root_frame, text="Kelompokkan Bahan", font=("Arial", 14),

              bg="#4CAF50", fg="white", width=25, height=2,

              command=lambda: show_sub_menu_kelompokkan_bahan(root_frame)).pack(pady=10)                        


    # Import dari menu_utama.py

    from menu_utama import tampilkan_halaman_utama


    # Tombol kembali ke menu utama

    tk.Button(root_frame, text="Kembali Ke Menu Utama", font=("Arial", 14),

              bg="gray", fg="white", width=25, height=2,

              command=lambda: tampilkan_halaman_utama(root_frame)).pack(pady=20)


Kalau mau dirapikan dan dipersingkat, kode menu_data_bahan_makanan.py bisa dibuat seperti ini:

# Menu Data Bahan Makanan
import tkinter as tk
from DataBahanMakanan import (
    sub_menu_lihat_daftar_bahan as lihat,
    sub_menu_cari_data_gizi as cari,
    sub_menu_kelompokkan_bahan as kelompok
)

def show_menu_data_bahan_makanan(root_frame):
    # Hapus widget lama
    for widget in root_frame.winfo_children():
        widget.destroy()

    # Judul
    tk.Label(root_frame, text="Data Bahan Makanan",
             font=("Arial", 18, "bold"),
             bg="green", fg="white", pady=10).pack(pady=20)

    # Daftar tombol sub menu
    menu_items = [
        ("Lihat Daftar Bahan", lihat.show_sub_menu_lihat_daftar_bahan),
        ("Cari Data Gizi", cari.show_sub_menu_cari_data_gizi),
        ("Kelompokkan Bahan", kelompok.show_sub_menu_kelompokkan_bahan),
    ]

    for text, cmd in menu_items:
        tk.Button(root_frame, text=text, font=("Arial", 14),
                  bg="#4CAF50", fg="white", width=25, height=2,
                  command=lambda c=cmd: c(root_frame)).pack(pady=10)

    # Tombol kembali
    from menu_utama import tampilkan_halaman_utama
    tk.Button(root_frame, text="Kembali Ke Menu Utama",
              font=("Arial", 14),
              bg="gray", fg="white", width=25, height=2,
              command=lambda: tampilkan_halaman_utama(root_frame)).pack(pady=20)

Perbedaan dan keunggulan versi ini:

  • Lebih ringkas karena daftar tombol sub menu disusun dalam list menu_items.
  • Menghindari pengulangan kode — tidak perlu tulis tk.Button(...) berulang kali untuk setiap menu.
  • Tetap mempertahankan tampilan dan fungsi yang sama seperti versi awal.

Kalau kamu mau, setelah ini saya bisa bikin semua sub menu (lihat, cari, kelompok) punya template tampilan seragam biar konsisten.


Bukankah Filter Kategori berisikan opsi pilihan: - Karbohidrat, Protein Hewani, Protein Nabati, Sayur-sayuran, Buah-buahan.
Atau menurut kamu pilihan kategori apa saja yang cocok dan ideal di sini unruk membuat resep masakan nantinya

Kalau tujuan akhirnya adalah membuat resep masakan, kategori bahan makanan memang sebaiknya disusun berdasarkan fungsi gizi dan peran dalam masakan, supaya nanti saat sistem menyusun resep, pemilihan bahan jadi lebih terarah.

Kategori yang kamu sebutkan sudah bagus, tapi bisa sedikit disempurnakan.

Berikut saran kategori ideal yang lebih lengkap:


1. Karbohidrat

  • Nasi, mie, roti, jagung, singkong, kentang, ubi, dll.
  • Sumber energi utama tubuh.

2. Protein Hewani

  • Daging merah (sapi, kambing), unggas (ayam, bebek), ikan, seafood, telur.
  • Untuk pertumbuhan, perbaikan jaringan, dan gizi otak.

3. Protein Nabati

  • Tahu, tempe, kacang-kacangan, edamame, oncom.
  • Alternatif protein untuk vegetarian atau pengganti hewani.

4. Sayur-sayuran

  • Bayam, kangkung, wortel, brokoli, kol, buncis, labu, dll.
  • Sumber vitamin, mineral, dan serat.

5. Buah-buahan

  • Jeruk, pisang, apel, pepaya, semangka, mangga, dll.
  • Sumber vitamin, mineral, antioksidan.

6. Bumbu & Rempah

  • Bawang merah, bawang putih, jahe, kunyit, cabai, ketumbar, garam, gula, dll.
  • Memberi rasa khas pada masakan.

7. Produk Olahan & Tambahan

  • Susu, keju, yogurt, mentega, minyak, kecap, saus.
  • Untuk memperkaya rasa atau tekstur.

Kalau nanti di sub menu Kelompok Bahan Makanan ini kategori dibuat seperti di atas, maka saat membuat resep:

  • Sistem bisa mengambil 1 bahan karbohidrat + 1 protein + 1-2 sayur + bumbu dasar → otomatis menghasilkan komposisi menu seimbang.
  • Bisa dibuat filter untuk masakan vegetarian (tanpa kategori protein hewani).
  • Bisa dibuat filter rendah kalori, tinggi protein, atau sesuai diet tertentu.

Kalau mau, aku bisa langsung buatkan fitur Filter Kategori ini di sub_menu_kelompokkan_bahan.py supaya pilihan kategori ini muncul di dropdown dan terhubung ke database.


mau, kamu buatkan fitur Filter Kategori ini di sub_menu_kelompokkan_bahan.py.

Baik, aku akan buatkan sub_menu_kelompokkan_bahan.py lengkap dengan fitur Filter Kategori yang terhubung ke database.
Fitur ini akan:

  • Menampilkan dropdown pilihan kategori (sesuai daftar yang sudah kita sepakati).
  • Menampilkan daftar bahan makanan yang masuk ke kategori itu.
  • Memungkinkan menambahkan atau mengedit kategori bahan langsung dari database.

Berikut kode lengkapnya:

# sub_menu_kelompokkan_bahan.py
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
import os

DATABASE_PATH = "/storage/emulated/0/AppJadi/SmartNutriChefAI/Database/data_bahan_makanan.db"

KATEGORI_LIST = [
    "Karbohidrat",
    "Protein Hewani",
    "Protein Nabati",
    "Sayur-sayuran",
    "Buah-buahan",
    "Bumbu & Rempah",
    "Produk Olahan & Tambahan"
]

def buat_tabel_kategori():
    conn = sqlite3.connect(DATABASE_PATH)
    c = conn.cursor()
    # Tambahkan kolom kategori jika belum ada
    c.execute("""
        CREATE TABLE IF NOT EXISTS bahan_makanan (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            nama TEXT NOT NULL,
            kalori INTEGER,
            protein REAL,
            lemak REAL,
            karbohidrat REAL,
            vitamin REAL,
            kategori TEXT
        )
    """)
    conn.commit()
    conn.close()

def ambil_data_kategori(kategori):
    conn = sqlite3.connect(DATABASE_PATH)
    c = conn.cursor()
    if kategori == "Semua":
        c.execute("SELECT nama, kalori, protein, lemak, karbohidrat, vitamin, kategori FROM bahan_makanan")
    else:
        c.execute("SELECT nama, kalori, protein, lemak, karbohidrat, vitamin, kategori FROM bahan_makanan WHERE kategori=?", (kategori,))
    hasil = c.fetchall()
    conn.close()
    return hasil

def show_sub_menu_kelompokkan_bahan(root_frame):
    from menu_data_bahan_makanan import show_menu_data_bahan_makanan

    buat_tabel_kategori()

    for widget in root_frame.winfo_children():
        widget.destroy()

    # Frame utama
    main_frame = tk.Frame(root_frame)
    main_frame.pack(fill="both", expand=True)

    # Judul
    tk.Label(main_frame, text="Kelompokkan Bahan Makanan", font=("Arial", 18, "bold"),
             bg="green", fg="white", pady=10).pack(fill="x")

    # Frame filter
    filter_frame = tk.Frame(main_frame)
    filter_frame.pack(fill="x", pady=10)

    tk.Label(filter_frame, text="Pilih Kategori:", font=("Arial", 12)).pack(side="left", padx=5)
    kategori_var = tk.StringVar(value="Semua")
    kategori_dropdown = ttk.Combobox(filter_frame, textvariable=kategori_var, values=["Semua"] + KATEGORI_LIST, state="readonly", width=30)
    kategori_dropdown.pack(side="left", padx=5)

    # Tombol filter
    def update_tabel():
        for i in tree.get_children():
            tree.delete(i)
        data = ambil_data_kategori(kategori_var.get())
        for item in data:
            tree.insert("", "end", values=item)

    tk.Button(filter_frame, text="Tampilkan", command=update_tabel, bg="#4CAF50", fg="white", font=("Arial", 12)).pack(side="left", padx=5)

    # Tabel
    kolom = ("Nama", "Kalori", "Protein", "Lemak", "Karbohidrat", "Vitamin", "Kategori")
    tree = ttk.Treeview(main_frame, columns=kolom, show="headings")
    for col in kolom:
        tree.heading(col, text=col)
        tree.column(col, width=150, anchor="center")
    tree.pack(fill="both", expand=True, padx=10, pady=10)

    # Isi tabel awal
    update_tabel()

    # Tombol kembali
    tk.Button(main_frame, text="Kembali ke Menu Data Bahan Makanan", font=("Arial", 14),
              bg="gray", fg="white", width=35, height=2,
              command=lambda: show_menu_data_bahan_makanan(root_frame)).pack(pady=10)

📌 Penjelasan Fitur:

  1. Dropdown Filter → berisi semua kategori dan opsi “Semua”.
  2. Tabel → menampilkan daftar bahan sesuai kategori yang dipilih.
  3. Koneksi Database → kolom kategori sudah ditambahkan di tabel bahan_makanan.
  4. Fungsi update_tabel() → memuat ulang data berdasarkan pilihan dropdown.

Kalau mau lebih interaktif, nanti kita bisa tambahkan tombol "Ubah Kategori Bahan" supaya user bisa memindahkan bahan ke kategori lain langsung dari sini.

Kalau kamu mau, aku bisa lanjut buatkan versi dengan fitur tambah/edit kategori bahan sekarang.
Itu akan bikin menu ini benar-benar powerful untuk pembuatan resep.


Tolong buat posisi tombol "Tampilkan" berada di baris setelah "Pilih Kategori" dengan format "Center" (tombol berada di sebelum tabel), Tambahkan tombol "Tambah Bahan" di kategori ini dan posisinya tombol berada setelah tabel (sebelum tombol "Kembali"). Tambahkan tombol "Hapus Bahan" di kategori ini dan posisinya tombol berada di samping tombol "Tambah Bahan" (sebelum tombol "Kembali"). Dan berikan contoh atau isi tabel awal, dan pada tabel buat kolom "kategori" berada di urutan setelah kolom "nama"

Oke, saya revisikan sub_menu_kelompokkan_bahan.py sesuai permintaan:

- Tombol "Tampilkan" berada di baris terpisah, center tepat sebelum tabel.

- Urutan kolom: Nama, Kategori, Kalori, Protein, Lemak, Karbohidrat, Vitamin.

- Ada data contoh bawaan jika database masih kosong.

- saya tambahkan tombol "Tambah Bahan" di bawah tabel, sebelum tombol "Kembali", lengkap dengan fungsi pop-up input agar user bisa langsung menambahkan bahan sesuai kategori yang sedang dipilih.

- saya tambahkan tombol "Hapus Bahan" di samping tombol "Tambah Bahan", posisinya tetap di bawah tabel dan sebelum tombol "Kembali".

Tombol ini akan menghapus data bahan yang dipilih di tabel.


Berikut kode revisinya:

# sub_menu_kelompokkan_bahan.py

import tkinter as tk

from tkinter import ttk, messagebox

import sqlite3


DATABASE_PATH = "/storage/emulated/0/AppJadi/SmartNutriChefAI/Database/data_bahan_makanan.db"


KATEGORI_LIST = [

    "Karbohidrat",

    "Protein Hewani",

    "Protein Nabati",

    "Sayur-sayuran",

    "Buah-buahan",

    "Bumbu & Rempah",

    "Produk Olahan & Tambahan"

]


def buat_tabel_kategori():

    conn = sqlite3.connect(DATABASE_PATH)

    c = conn.cursor()

    c.execute("""

        CREATE TABLE IF NOT EXISTS bahan_makanan (

            id INTEGER PRIMARY KEY AUTOINCREMENT,

            nama TEXT NOT NULL,

            kategori TEXT,

            kalori INTEGER,

            protein REAL,

            lemak REAL,

            karbohidrat REAL,

            vitamin REAL

        )

    """)

    conn.commit()


    c.execute("SELECT COUNT(*) FROM bahan_makanan")

    if c.fetchone()[0] == 0:

        data_awal = [

            ("Nasi Putih", "Karbohidrat", 175, 3.5, 0.3, 40, 0),

            ("Ayam", "Protein Hewani", 239, 27, 14, 0, 0),

            ("Telur", "Protein Hewani", 155, 13, 11, 1.1, 0),

            ("Wortel", "Sayur-sayuran", 41, 0.9, 0.2, 10, 0),

            ("Pisang", "Buah-buahan", 89, 1.1, 0.3, 23, 0)

        ]

        c.executemany("INSERT INTO bahan_makanan (nama, kategori, kalori, protein, lemak, karbohidrat, vitamin) VALUES (?, ?, ?, ?, ?, ?, ?)", data_awal)

        conn.commit()

    conn.close()


def ambil_data_kategori(kategori):

    conn = sqlite3.connect(DATABASE_PATH)

    c = conn.cursor()

    if kategori == "Semua":

        c.execute("SELECT id, nama, kategori, kalori, protein, lemak, karbohidrat, vitamin FROM bahan_makanan")

    else:

        c.execute("SELECT id, nama, kategori, kalori, protein, lemak, karbohidrat, vitamin FROM bahan_makanan WHERE kategori=?", (kategori,))

    hasil = c.fetchall()

    conn.close()

    return hasil


def tambah_bahan_popup(kategori_awal, refresh_callback):

    popup = tk.Toplevel()

    popup.title("Tambah Bahan")

    popup.geometry("400x400")


    tk.Label(popup, text="Nama Bahan:").pack(pady=5)

    entry_nama = tk.Entry(popup, width=30)

    entry_nama.pack()


    tk.Label(popup, text="Kategori:").pack(pady=5)

    kategori_var = tk.StringVar(value=kategori_awal if kategori_awal != "Semua" else KATEGORI_LIST[0])

    ttk.Combobox(popup, textvariable=kategori_var, values=KATEGORI_LIST, state="readonly").pack()


    tk.Label(popup, text="Kalori (kkal):").pack(pady=5)

    entry_kalori = tk.Entry(popup, width=30)

    entry_kalori.pack()


    tk.Label(popup, text="Protein (g):").pack(pady=5)

    entry_protein = tk.Entry(popup, width=30)

    entry_protein.pack()


    tk.Label(popup, text="Lemak (g):").pack(pady=5)

    entry_lemak = tk.Entry(popup, width=30)

    entry_lemak.pack()


    tk.Label(popup, text="Karbohidrat (g):").pack(pady=5)

    entry_karbo = tk.Entry(popup, width=30)

    entry_karbo.pack()


    tk.Label(popup, text="Vitamin (mg):").pack(pady=5)

    entry_vitamin = tk.Entry(popup, width=30)

    entry_vitamin.pack()


    def simpan():

        nama = entry_nama.get().strip()

        kategori = kategori_var.get()

        try:

            kalori = float(entry_kalori.get())

            protein = float(entry_protein.get())

            lemak = float(entry_lemak.get())

            karbo = float(entry_karbo.get())

            vitamin = float(entry_vitamin.get())

        except ValueError:

            messagebox.showerror("Error", "Pastikan semua nilai gizi diisi dengan angka.")

            return


        if not nama:

            messagebox.showerror("Error", "Nama bahan tidak boleh kosong.")

            return


        conn = sqlite3.connect(DATABASE_PATH)

        c = conn.cursor()

        c.execute("INSERT INTO bahan_makanan (nama, kategori, kalori, protein, lemak, karbohidrat, vitamin) VALUES (?, ?, ?, ?, ?, ?, ?)",

                  (nama, kategori, kalori, protein, lemak, karbo, vitamin))

        conn.commit()

        conn.close()


        messagebox.showinfo("Sukses", f"{nama} berhasil ditambahkan.")

        popup.destroy()

        refresh_callback()


    tk.Button(popup, text="Simpan", command=simpan, bg="#4CAF50", fg="white").pack(pady=10)


def hapus_bahan(tree, refresh_callback):

    selected_item = tree.selection()

    if not selected_item:

        messagebox.showwarning("Peringatan", "Pilih bahan yang ingin dihapus.")

        return

    

    confirm = messagebox.askyesno("Konfirmasi", "Yakin ingin menghapus bahan terpilih?")

    if not confirm:

        return

    

    item_id = tree.item(selected_item[0], "values")[0]  # ID ada di kolom pertama

    conn = sqlite3.connect(DATABASE_PATH)

    c = conn.cursor()

    c.execute("DELETE FROM bahan_makanan WHERE id=?", (item_id,))

    conn.commit()

    conn.close()

    

    messagebox.showinfo("Sukses", "Bahan berhasil dihapus.")

    refresh_callback()


def show_sub_menu_kelompokkan_bahan(root_frame):

    from menu_data_bahan_makanan import show_menu_data_bahan_makanan


    buat_tabel_kategori()


    for widget in root_frame.winfo_children():

        widget.destroy()


    main_frame = tk.Frame(root_frame)

    main_frame.pack(fill="both", expand=True)


    tk.Label(main_frame, text="Kelompokkan Bahan Makanan", font=("Arial", 18, "bold"),

             bg="green", fg="white", pady=10).pack(fill="x")


    filter_frame = tk.Frame(main_frame)

    filter_frame.pack(fill="x", pady=10)


    tk.Label(filter_frame, text="Pilih Kategori:", font=("Arial", 12)).pack(side="left", padx=5)

    kategori_var = tk.StringVar(value="Semua")

    kategori_dropdown = ttk.Combobox(filter_frame, textvariable=kategori_var, values=["Semua"] + KATEGORI_LIST, state="readonly", width=30)

    kategori_dropdown.pack(side="left", padx=5)


    tk.Button(main_frame, text="Tampilkan", command=lambda: update_tabel(), bg="#4CAF50", fg="white", font=("Arial", 12)).pack(pady=5)


    kolom = ("ID", "Nama", "Kategori", "Kalori", "Protein", "Lemak", "Karbohidrat", "Vitamin")

    tree = ttk.Treeview(main_frame, columns=kolom, show="headings")

    for col in kolom:

        tree.heading(col, text=col)

        tree.column(col, width=150, anchor="center")

    tree.pack(fill="both", expand=True, padx=10, pady=10)


    def update_tabel():

        for i in tree.get_children():

            tree.delete(i)

        data = ambil_data_kategori(kategori_var.get())

        for item in data:

            tree.insert("", "end", values=item)


    update_tabel()


    # Frame tombol Tambah & Hapus

    button_action_frame = tk.Frame(main_frame)

    button_action_frame.pack(pady=5)


    tk.Button(button_action_frame, text="Tambah Bahan", font=("Arial", 12),

              bg="#2196F3", fg="white", width=20,

              command=lambda: tambah_bahan_popup(kategori_var.get(), update_tabel)).pack(side="left", padx=5)


    tk.Button(button_action_frame, text="Hapus Bahan", font=("Arial", 12),

              bg="red", fg="white", width=20,

              command=lambda: hapus_bahan(tree, update_tabel)).pack(side="left", padx=5)


    # Tombol kembali

    tk.Button(main_frame, text="Kembali ke Menu Data Bahan Makanan", font=("Arial", 14),

              bg="gray", fg="white", width=35, height=2,

              command=lambda: show_menu_data_bahan_makanan(root_frame)).pack(pady=10)


🔹 Perubahan dari versi sebelumnya:

1. Urutan kolom tabel → Nama, Kategori, lalu gizi.

2. Tombol “Tampilkan” → pindah ke baris baru, center sebelum tabel.

3. Data contoh bawaan → otomatis masuk jika database kosong.

4. Lebar kolom sama & data center supaya rapi.

5. Tambah tombol "Tambah Bahan" setelah tabel dan sebelum tombol kembali.

6. Pop-up input memungkinkan user menambahkan bahan sesuai kategori yang sedang dipilih.

7. Jika kategori dropdown di pop-up dipilih, akan masuk ke DB dan tabel otomatis refresh.

8. Menambahkan fungsi hapus_bahan() untuk menghapus data dari database berdasarkan ID.

9. Mengubah kolom tabel agar ID bahan ada di kolom pertama (agar tahu data mana yang dihapus).

10. Menambahkan frame horizontal di bawah tabel untuk menempatkan tombol Tambah Bahan dan Hapus Bahan berdampingan.

11. Memastikan tabel otomatis refresh setelah menambah atau menghapus bahan.

Kalau mau, saya bisa bikin ID ini tidak ditampilkan ke user (disembunyikan dari tampilan tapi tetap ada di data) supaya tabel kelihatan lebih rapi.

Mau saya buat seperti itu?


Sampai saat ini perubahan, penyempurnaan, dan tambahan file pada applikasi SmartNutriChefAI adalah:

1. menu_data_bahan_makanan.py

Kode programnya adalah berikut:


# Menu Data Bahan Makanan

import tkinter as tk

from DataBahanMakanan import (

    sub_menu_lihat_daftar_bahan as lihat,

    sub_menu_cari_data_gizi as cari,

    sub_menu_kelompokkan_bahan as kelompok

)


def show_menu_data_bahan_makanan(root_frame):

    # Hapus widget lama

    for widget in root_frame.winfo_children():

        widget.destroy()


    # Judul

    tk.Label(root_frame, text="Data Bahan Makanan",

             font=("Arial", 18, "bold"),

             bg="green", fg="white", pady=10).pack(pady=20)


    # Daftar tombol sub menu

    menu_items = [

        ("Lihat Daftar Bahan", lihat.show_sub_menu_lihat_daftar_bahan),

        ("Cari Data Gizi", cari.show_sub_menu_cari_data_gizi),

        ("Kelompokkan Bahan", kelompok.show_sub_menu_kelompokkan_bahan),

    ]


    for text, cmd in menu_items:

        tk.Button(root_frame, text=text, font=("Arial", 14),

                  bg="#4CAF50", fg="white", width=25, height=2,

                  command=lambda c=cmd: c(root_frame)).pack(pady=10)


    # Tombol kembali

    from menu_utama import tampilkan_halaman_utama

    tk.Button(root_frame, text="Kembali Ke Menu Utama",

              font=("Arial", 14),

              bg="gray", fg="white", width=25, height=2,

              command=lambda: tampilkan_halaman_utama(root_frame)).pack(pady=20)


2. sub_menu_kelompokkan_bahan.py

Kode programnya adalah berikut:


# sub_menu_kelompokkan_bahan.py

import tkinter as tk

from tkinter import ttk, messagebox

import sqlite3


DATABASE_PATH = "/storage/emulated/0/AppJadi/SmartNutriChefAI/Database/data_bahan_makanan.db"


KATEGORI_LIST = [

    "Karbohidrat",

    "Protein Hewani",

    "Protein Nabati",

    "Sayur-sayuran",

    "Buah-buahan",

    "Bumbu & Rempah",

    "Produk Olahan & Tambahan"

]


def buat_tabel_kategori():

    conn = sqlite3.connect(DATABASE_PATH)

    c = conn.cursor()

    c.execute("""

        CREATE TABLE IF NOT EXISTS bahan_makanan (

            id INTEGER PRIMARY KEY AUTOINCREMENT,

            nama TEXT NOT NULL,

            kategori TEXT,

            kalori INTEGER,

            protein REAL,

            lemak REAL,

            karbohidrat REAL,

            vitamin REAL

        )

    """)

    conn.commit()


    c.execute("SELECT COUNT(*) FROM bahan_makanan")

    if c.fetchone()[0] == 0:

        data_awal = [

            ("Nasi Putih", "Karbohidrat", 175, 3.5, 0.3, 40, 0),

            ("Ayam", "Protein Hewani", 239, 27, 14, 0, 0),

            ("Telur", "Protein Hewani", 155, 13, 11, 1.1, 0),

            ("Wortel", "Sayur-sayuran", 41, 0.9, 0.2, 10, 0),

            ("Pisang", "Buah-buahan", 89, 1.1, 0.3, 23, 0)

        ]

        c.executemany("INSERT INTO bahan_makanan (nama, kategori, kalori, protein, lemak, karbohidrat, vitamin) VALUES (?, ?, ?, ?, ?, ?, ?)", data_awal)

        conn.commit()

    conn.close()


def ambil_data_kategori(kategori):

    conn = sqlite3.connect(DATABASE_PATH)

    c = conn.cursor()

    if kategori == "Semua":

        c.execute("SELECT id, nama, kategori, kalori, protein, lemak, karbohidrat, vitamin FROM bahan_makanan")

    else:

        c.execute("SELECT id, nama, kategori, kalori, protein, lemak, karbohidrat, vitamin FROM bahan_makanan WHERE kategori=?", (kategori,))

    hasil = c.fetchall()

    conn.close()

    return hasil


def tambah_bahan_popup(kategori_awal, refresh_callback):

    popup = tk.Toplevel()

    popup.title("Tambah Bahan")

    popup.geometry("450x750")


    tk.Label(popup, text="Nama Bahan:").pack(pady=5)

    entry_nama = tk.Entry(popup, width=30)

    entry_nama.pack()


    tk.Label(popup, text="Kategori:").pack(pady=5)

    kategori_var = tk.StringVar(value=kategori_awal if kategori_awal != "Semua" else KATEGORI_LIST[0])

    ttk.Combobox(popup, textvariable=kategori_var, values=KATEGORI_LIST, state="readonly").pack()


    tk.Label(popup, text="Kalori (kkal):").pack(pady=5)

    entry_kalori = tk.Entry(popup, width=28)

    entry_kalori.pack()


    tk.Label(popup, text="Protein (g):").pack(pady=5)

    entry_protein = tk.Entry(popup, width=28)

    entry_protein.pack()


    tk.Label(popup, text="Lemak (g):").pack(pady=5)

    entry_lemak = tk.Entry(popup, width=28)

    entry_lemak.pack()


    tk.Label(popup, text="Karbohidrat (g):").pack(pady=5)

    entry_karbo = tk.Entry(popup, width=28)

    entry_karbo.pack()


    tk.Label(popup, text="Vitamin (mg):").pack(pady=5)

    entry_vitamin = tk.Entry(popup, width=28)

    entry_vitamin.pack()


    def simpan():

        nama = entry_nama.get().strip()

        kategori = kategori_var.get()

        try:

            kalori = float(entry_kalori.get())

            protein = float(entry_protein.get())

            lemak = float(entry_lemak.get())

            karbo = float(entry_karbo.get())

            vitamin = float(entry_vitamin.get())

        except ValueError:

            messagebox.showerror("Error", "Pastikan semua nilai gizi diisi dengan angka.")

            return


        if not nama:

            messagebox.showerror("Error", "Nama bahan tidak boleh kosong.")

            return


        conn = sqlite3.connect(DATABASE_PATH)

        c = conn.cursor()

        c.execute("INSERT INTO bahan_makanan (nama, kategori, kalori, protein, lemak, karbohidrat, vitamin) VALUES (?, ?, ?, ?, ?, ?, ?)",

                  (nama, kategori, kalori, protein, lemak, karbo, vitamin))

        conn.commit()

        conn.close()


        messagebox.showinfo("Sukses", f"{nama} berhasil ditambahkan.")

        popup.destroy()

        refresh_callback()


    tk.Button(popup, text="Simpan", command=simpan, bg="#4CAF50", font=("Arial", 10, "bold"), fg="white").pack(pady=10)


def hapus_bahan(tree, refresh_callback):

    selected_item = tree.selection()

    if not selected_item:

        messagebox.showwarning("Peringatan", "Pilih bahan yang ingin dihapus.")

        return

    

    confirm = messagebox.askyesno("Konfirmasi", "Yakin ingin menghapus bahan terpilih?")

    if not confirm:

        return

    

    item_id = tree.item(selected_item[0], "values")[0]  # ID ada di kolom pertama

    conn = sqlite3.connect(DATABASE_PATH)

    c = conn.cursor()

    c.execute("DELETE FROM bahan_makanan WHERE id=?", (item_id,))

    conn.commit()

    conn.close()

    

    messagebox.showinfo("Sukses", "Bahan berhasil dihapus.")

    refresh_callback()


def show_sub_menu_kelompokkan_bahan(root_frame):

    from menu_data_bahan_makanan import show_menu_data_bahan_makanan


    buat_tabel_kategori()


    for widget in root_frame.winfo_children():

        widget.destroy()


    main_frame = tk.Frame(root_frame)

    main_frame.pack(fill="both", expand=True)


    tk.Label(main_frame, text="Kelompok Bahan Makanan", font=("Arial", 16, "bold"),

             bg="green", fg="white", pady=10).pack(fill="x")


    filter_frame = tk.Frame(main_frame)

    filter_frame.pack(fill="x", pady=10)


    tk.Label(filter_frame, text="Pilih Kategori:", font=("Arial", 12)).pack(side="left", padx=5)

    kategori_var = tk.StringVar(value="Semua")

    kategori_dropdown = ttk.Combobox(filter_frame, textvariable=kategori_var, values=["Semua"] + KATEGORI_LIST, state="readonly", width=28)

    kategori_dropdown.pack(side="left", padx=5)


    tk.Button(main_frame, text="Tampilkan", command=lambda: update_tabel(), bg="#4CAF50", fg="white", font=("Arial", 12)).pack(pady=5)


    kolom = ("ID", "Nama", "Kategori", "Kalori", "Protein", "Lemak", "Karbohidrat", "Vitamin")

    tree = ttk.Treeview(main_frame, columns=kolom, show="headings")

    for col in kolom:

        tree.heading(col, text=col)

        tree.column(col, width=150, anchor="center")

    tree.pack(fill="both", expand=True, padx=10, pady=10)


    def update_tabel():

        for i in tree.get_children():

            tree.delete(i)

        data = ambil_data_kategori(kategori_var.get())

        for item in data:

            tree.insert("", "end", values=item)


    update_tabel()


    # Frame tombol Tambah & Hapus

    button_action_frame = tk.Frame(main_frame)

    button_action_frame.pack(pady=5)


    tk.Button(button_action_frame, text="Tambah Bahan", font=("Arial", 11),

              bg="#2196F3", fg="white", width=15,

              command=lambda: tambah_bahan_popup(kategori_var.get(), update_tabel)).pack(side="left", padx=5)


    tk.Button(button_action_frame, text="Hapus Bahan", font=("Arial", 11),

              bg="red", fg="white", width=15,

              command=lambda: hapus_bahan(tree, update_tabel)).pack(side="left", padx=5)


    # Tombol kembali

    tk.Button(main_frame, text="Kembali", font=("Arial", 16),

              bg="gray", fg="white", width=25, height=2,

              command=lambda: show_menu_data_bahan_makanan(root_frame)).pack(pady=10)


Bersambung Ke:  Konten Sub Menu "Analisis Kombinasi Bahan"



Comments

Popular posts from this blog

Isi Menu "Setting"

Isi Menu "Riwayat Aktivitas" (Bagian 2)