Konten Sub Menu "Analisis Kombinasi Bahan"
Isi Menu "Data Bahan Makanan"
(Konten Sub Menu "Analisis Kombinasi Bahan")
3. Sub Menu “Analisis Kombinasi Bahan"
Sekarang kita masuk ke Menu Data Bahan Makanan, kita lanjut membuat konten Sub Menu "Analisis Kombinasi Bahan"
Oke, berarti kita akan menambah Sub Menu "Analisis Kombinasi Bahan" di Menu Data Bahan Makanan.
Konsepnya, sub menu ini akan memungkinkan user:
- Memilih beberapa bahan makanan dari database.
- Menampilkan total kandungan gizi dari semua bahan yang dipilih.
- Nantinya bisa kita kembangkan untuk memberi saran menu atau cek kecukupan gizi.
Kalau kamu setuju, alur fiturnya akan seperti ini:
- Pilih bahan makanan dari list tabel (dengan checkbox atau multi-select).
- Tekan tombol "Analisis".
- Tampil total kalori, protein, lemak, karbohidrat, dan vitamin dari bahan yang dipilih.
- Ada tombol "Kembali" ke Menu Data Bahan Makanan.
Kalau oke, saya bisa langsung buatkan file sub_menu_analisis_kombinasi_bahan.py sekarang beserta update menu_data_bahan_makanan.py untuk menambah tombol sub menu baru ini.
Mau saya langsung buatkan?
Buatkan file sub_menu_analisis_kombinasi_bahan.py sekarang beserta update menu_data_bahan_makanan.py untuk menambah tombol sub menu baru ini.
Baik, saya buatkan langsung dua file itu.
Pertama, sub_menu_analisis_kombinasi_bahan.py untuk fitur Analisis Kombinasi Bahan.
Kedua, update menu_data_bahan_makanan.py untuk menambahkan tombol aksesnya.
๐ File: sub_menu_analisis_kombinasi_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"
def ambil_data_bahan():
conn = sqlite3.connect(DATABASE_PATH)
c = conn.cursor()
c.execute("SELECT id, nama, kalori, protein, lemak, karbohidrat, vitamin FROM bahan_makanan")
hasil = c.fetchall()
conn.close()
return hasil
def show_sub_menu_analisis_kombinasi_bahan(root_frame):
from menu_data_bahan_makanan import show_menu_data_bahan_makanan
for widget in root_frame.winfo_children():
widget.destroy()
tk.Label(root_frame, text="Analisis Kombinasi Bahan", font=("Arial", 18, "bold"),
bg="green", fg="white", pady=10).pack(pady=20)
# Frame tabel
frame_tabel = tk.Frame(root_frame)
frame_tabel.pack(fill="both", expand=True, padx=10, pady=10)
kolom = ("Pilih", "Nama", "Kalori (kkal)", "Protein (g)", "Lemak (g)", "Karbohidrat (g)", "Vitamin")
tree = ttk.Treeview(frame_tabel, columns=kolom, show="headings", selectmode="extended", height=12)
for col in kolom:
anchor = "center" if col != "Nama" and col != "Vitamin" else "w"
tree.heading(col, text=col)
tree.column(col, width=140 if col != "Nama" else 200, anchor=anchor)
# Load data ke tabel
data_bahan = ambil_data_bahan()
if not data_bahan:
tk.Label(root_frame, text="Belum ada data bahan makanan.",
font=("Arial", 12), fg="red").pack(pady=10)
else:
for item in data_bahan:
tree.insert("", "end", values=("", item[1], item[2], item[3], item[4], item[5], item[6]))
tree.pack(fill="both", expand=True)
# Tombol Analisis
def analisis_bahan():
selected_items = tree.selection()
if not selected_items:
messagebox.showwarning("Peringatan", "Pilih minimal satu bahan untuk dianalisis.")
return
total_kalori = total_protein = total_lemak = total_karbohidrat = 0
vitamin_list = []
for item_id in selected_items:
item = tree.item(item_id)["values"]
total_kalori += item[2]
total_protein += item[3]
total_lemak += item[4]
total_karbohidrat += item[5]
if item[6] and item[6] not in vitamin_list:
vitamin_list.append(item[6])
hasil = f"""
Total Kalori: {total_kalori} kkal
Total Protein: {total_protein} g
Total Lemak: {total_lemak} g
Total Karbohidrat: {total_karbohidrat} g
Vitamin: {", ".join(vitamin_list)}
"""
messagebox.showinfo("Hasil Analisis", hasil)
tk.Button(root_frame, text="Analisis", font=("Arial", 14), bg="#4CAF50", fg="white",
width=20, height=2, command=analisis_bahan).pack(pady=10)
# Tombol kembali
tk.Button(root_frame, text="Kembali ke Menu Data Bahan Makanan", font=("Arial", 14),
bg="gray", fg="white", width=30, height=2,
command=lambda: show_menu_data_bahan_makanan(root_frame)).pack(pady=20)
๐ Update: menu_data_bahan_makanan.py
# 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
from DataBahanMakanan.sub_menu_analisis_kombinasi_bahan import show_sub_menu_analisis_kombinasi_bahan
def show_menu_data_bahan_makanan(root_frame):
for widget in root_frame.winfo_children():
widget.destroy()
tk.Label(root_frame, text="Data Bahan Makanan", font=("Arial", 18, "bold"),
bg="green", fg="white", pady=10).pack(pady=20)
menu_list = [
("Lihat Daftar Bahan", show_sub_menu_lihat_daftar_bahan),
("Cari Data Gizi", show_sub_menu_cari_data_gizi),
("Kelompokkan Bahan", show_sub_menu_kelompokkan_bahan),
("Analisis Kombinasi Bahan", show_sub_menu_analisis_kombinasi_bahan)
]
for text, cmd in menu_list:
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)
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)
Kalau kita jalankan, akan muncul sub menu baru "Analisis Kombinasi Bahan".
Di sana bisa pilih beberapa bahan dari tabel lalu klik Analisis untuk melihat total gizi.
Kalau mau, fitur ini nanti bisa saya kembangkan supaya hasil analisisnya muncul langsung di layar (bukan pop-up) dan otomatis terupdate saat user memilih bahan.
Kamu mau saya buat langsung begitu atau kita coba dulu versi ini?
Ketika tombol "Analisis" ditekan, maka tidak bisa beberapa bahan (dengan checkbox atau multi-select). dianalisa
Betul, dari kode yang saya buat tadi memang belum ada mekanisme checkbox di tabel Treeview, dan multi-select pun hanya bisa lewat CTRL+klik atau SHIFT+klik — yang di HP Android jelas tidak nyaman.
Kalau mau pilih beberapa bahan lalu dianalisis dengan cara checkbox, kita perlu ubah desain tabelnya sedikit:
- Tambah kolom “Pilih” yang berisi tanda centang (✔) atau kosong.
- Klik pada kolom itu akan mengganti statusnya dari “kosong” menjadi “✔” dan sebaliknya.
- Analisis mengambil semua baris yang punya tanda centang.
๐ Keunggulan metode ini:
- Tidak tergantung pada multi-select bawaan Tkinter yang sulit di HP.
- User cukup tap kolom pertama untuk memilih bahan.
Kalau kamu setuju, saya bisa langsung revisikan sub_menu_analisis_kombinasi_bahan.py supaya:
- Tabel ada kolom checkbox.
- Klik kolom itu akan toggle centang.
- Analisis menghitung semua yang dicentang.
Mau saya buatkan revisinya langsung?
Saya setuju, kamu bisa langsung revisikan sub_menu_analisis_kombinasi_bahan.py supaya:
- Tabel ada kolom checkbox.
- Klik kolom itu akan toggle centang.
- Analisis menghitung semua yang dicentang.
๐น Perubahan utama:
1. Kolom "Pilih" ditambahkan untuk centang.
2. Klik kolom pertama akan toggle “✔” atau kosong.
3. Analisis hanya menghitung yang dicentang.
Dengan ini:
- Label instruksi muncul tepat di bawah tabel.
- Format teks center (otomatis karena pack tanpa anchor di dalam frame yang penuh).
- Warna teks biru supaya menonjol.
Kalau mau, label ini juga bisa dibuat bold + italic supaya seperti catatan penting.
Mau saya buat begitu?
Pada Hasil Analisis, tambahkan hitungan "Total Vitamin", satuan vitamin adalah IU (International Unit).
Oke, saya revisikan fungsi analisis_bahan() supaya hasil analisis juga menampilkan Total Vitamin dengan satuan IU.
Berikut revisinya:
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"
def ambil_data_bahan():
conn = sqlite3.connect(DATABASE_PATH)
c = conn.cursor()
c.execute("SELECT id, nama, kalori, protein, lemak, karbohidrat, vitamin FROM bahan_makanan")
hasil = c.fetchall()
conn.close()
return hasil
def show_sub_menu_analisis_kombinasi_bahan(root_frame):
from menu_data_bahan_makanan import show_menu_data_bahan_makanan
for widget in root_frame.winfo_children():
widget.destroy()
# Frame utama
tk.Label(root_frame, text="Analisis Kombinasi Bahan", font=("Arial", 18, "bold"),
bg="green", fg="white", pady=10).pack(pady=10)
# Scrollable frame
container = tk.Frame(root_frame)
container.pack(fill="both", expand=True)
canvas = tk.Canvas(container)
canvas.pack(side="left", fill="both", expand=True)
scrollbar_y = tk.Scrollbar(container, orient="vertical", command=canvas.yview)
scrollbar_y.pack(side="right", fill="y")
canvas.configure(yscrollcommand=scrollbar_y.set)
content_frame = tk.Frame(canvas)
canvas.create_window((0, 0), window=content_frame, anchor="nw")
def on_frame_configure(event):
canvas.configure(scrollregion=canvas.bbox("all"))
content_frame.bind("<Configure>", on_frame_configure)
# Tabel dengan kolom checkbox
kolom = ("Pilih", "Nama", "Kalori", "Protein", "Lemak", "Karbohidrat", "Vitamin")
tree = ttk.Treeview(content_frame, columns=kolom, show="headings", selectmode="none")
tree.heading("Pilih", text="✔")
tree.heading("Nama", text="Nama")
tree.heading("Kalori", text="Kalori (kkal)")
tree.heading("Protein", text="Protein (g)")
tree.heading("Lemak", text="Lemak (g)")
tree.heading("Karbohidrat", text="Karbohidrat (g)")
tree.heading("Vitamin", text="Vitamin")
tree.column("Pilih", width=50, anchor="center")
tree.column("Nama", width=200)
tree.column("Kalori", width=100, anchor="center")
tree.column("Protein", width=100, anchor="center")
tree.column("Lemak", width=100, anchor="center")
tree.column("Karbohidrat", width=130, anchor="center")
tree.column("Vitamin", width=150, anchor="center")
tree.pack(padx=10, pady=10, fill="both", expand=True)
# Muat data awal
data_bahan = ambil_data_bahan()
for row in data_bahan:
tree.insert("", "end", values=("", row[1], row[2], row[3], row[4], row[5], row[6]))
# Toggle centang saat klik kolom "Pilih"
def on_tree_click(event):
region = tree.identify_region(event.x, event.y)
if region == "cell":
col = tree.identify_column(event.x)
if col == "#1": # Kolom "Pilih"
item = tree.identify_row(event.y)
current_val = tree.item(item, "values")[0]
new_val = "✔" if current_val == "" else ""
vals = list(tree.item(item, "values"))
vals[0] = new_val
tree.item(item, values=vals)
tree.bind("<Button-1>", on_tree_click)
# Label instruksi di bawah tabel
instruksi_label = tk.Label(
content_frame,
text="Beri centang pada beberapa bahan yang akan dianalisis",
font=("Arial", 12),
fg="blue"
)
instruksi_label.pack(pady=5)
# Fungsi Analisis
def analisis_bahan():
selected_items = []
for child in tree.get_children():
vals = tree.item(child, "values")
if vals[0] == "✔":
selected_items.append(vals)
if not selected_items:
messagebox.showwarning("Peringatan", "Pilih minimal 1 bahan untuk dianalisis!")
return
total_kalori = sum(float(item[2]) for item in selected_items)
total_protein = sum(float(item[3]) for item in selected_items)
total_lemak = sum(float(item[4]) for item in selected_items)
total_karbo = sum(float(item[5]) for item in selected_items)
total_vitamin = sum(float(item[6]) for item in selected_items)
hasil = (
f"Jumlah Bahan: {len(selected_items)}\n"
f"Total Kalori: {total_kalori} kkal\n"
f"Total Protein: {total_protein} g\n"
f"Total Lemak: {total_lemak} g\n"
f"Total Karbohidrat: {total_karbo} g\n"
f"Total Vitamin: {total_vitamin} IU"
)
messagebox.showinfo("Hasil Analisis", hasil)
# Tombol Analisis & Kembali
tk.Button(content_frame, text="Analisis", font=("Arial", 14),
bg="#4CAF50", fg="white", width=20, height=2,
command=analisis_bahan).pack(pady=10)
tk.Button(root_frame, text="Kembali ke Menu Data Bahan Makanan", font=("Arial", 14),
bg="gray", fg="white", width=30, height=2,
command=lambda: show_menu_data_bahan_makanan(root_frame)).pack(pady=10)
๐น Perubahan yang saya buat:
- Menambahkan variabel total_vitamin
- Menambahkan Total Vitamin (IU) ke dalam string hasil.
Kalau mau, saya bisa langsung gabungkan revisi ini ke seluruh file sub_menu_analisis_kombinasi_bahan.py biar kamu tinggal copy-paste saja.
Mau saya buat langsung file utuhnya?
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.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
from DataBahanMakanan.sub_menu_analisis_kombinasi_bahan import show_sub_menu_analisis_kombinasi_bahan
def show_menu_data_bahan_makanan(root_frame):
for widget in root_frame.winfo_children():
widget.destroy()
tk.Label(root_frame, text="Data Bahan Makanan", font=("Arial", 18, "bold"),
bg="green", fg="white", pady=10).pack(pady=20)
menu_list = [
("Lihat Daftar Bahan", show_sub_menu_lihat_daftar_bahan),
("Cari Data Gizi", show_sub_menu_cari_data_gizi),
("Kelompokkan Bahan", show_sub_menu_kelompokkan_bahan),
("Analisis Kombinasi Bahan", show_sub_menu_analisis_kombinasi_bahan)
]
for text, cmd in menu_list:
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)
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_analisis_kombinasi_bahan.py
Kode programnya adalah berikut:
# Sub Menu Analisis Kombinasi Bahan
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"
def ambil_data_bahan():
conn = sqlite3.connect(DATABASE_PATH)
c = conn.cursor()
c.execute("SELECT id, nama, kalori, protein, lemak, karbohidrat, vitamin FROM bahan_makanan")
hasil = c.fetchall()
conn.close()
return hasil
def show_sub_menu_analisis_kombinasi_bahan(root_frame):
from menu_data_bahan_makanan import show_menu_data_bahan_makanan
for widget in root_frame.winfo_children():
widget.destroy()
# Frame utama
tk.Label(root_frame, text="Analisis Kombinasi Bahan", font=("Arial", 16, "bold"),
bg="green", fg="white", pady=10).pack(pady=10)
# Scrollable frame
container = tk.Frame(root_frame)
container.pack(fill="both", expand=True)
canvas = tk.Canvas(container)
canvas.pack(side="left", fill="both", expand=True)
scrollbar_y = tk.Scrollbar(container, orient="vertical", command=canvas.yview)
scrollbar_y.pack(side="right", fill="y")
canvas.configure(yscrollcommand=scrollbar_y.set)
content_frame = tk.Frame(canvas)
canvas.create_window((0, 0), window=content_frame, anchor="nw")
def on_frame_configure(event):
canvas.configure(scrollregion=canvas.bbox("all"))
content_frame.bind("<Configure>", on_frame_configure)
# Tabel dengan kolom checkbox
kolom = ("Pilih", "Nama", "Kalori", "Protein", "Lemak", "Karbohidrat", "Vitamin")
tree = ttk.Treeview(content_frame, columns=kolom, show="headings", selectmode="none")
tree.heading("Pilih", text="✔")
tree.heading("Nama", text="Nama")
tree.heading("Kalori", text="Kalori (kkal)")
tree.heading("Protein", text="Protein (g)")
tree.heading("Lemak", text="Lemak (g)")
tree.heading("Karbohidrat", text="Karbohidrat (g)")
tree.heading("Vitamin", text="Vitamin (IU)")
tree.column("Pilih", width=50, anchor="center")
tree.column("Nama", width=200)
tree.column("Kalori", width=100, anchor="center")
tree.column("Protein", width=100, anchor="center")
tree.column("Lemak", width=100, anchor="center")
tree.column("Karbohidrat", width=130, anchor="center")
tree.column("Vitamin", width=150, anchor="center")
tree.pack(padx=10, pady=10, fill="both", expand=True)
# Muat data awal
data_bahan = ambil_data_bahan()
for row in data_bahan:
tree.insert("", "end", values=("", row[1], row[2], row[3], row[4], row[5], row[6]))
# Toggle centang saat klik kolom "Pilih"
def on_tree_click(event):
region = tree.identify_region(event.x, event.y)
if region == "cell":
col = tree.identify_column(event.x)
if col == "#1": # Kolom "Pilih"
item = tree.identify_row(event.y)
current_val = tree.item(item, "values")[0]
new_val = "✔" if current_val == "" else ""
vals = list(tree.item(item, "values"))
vals[0] = new_val
tree.item(item, values=vals)
tree.bind("<Button-1>", on_tree_click)
# Label instruksi di bawah tabel
instruksi_label = tk.Label(
content_frame,
text="Beri centang pada beberapa bahan \nyang akan dianalisis",
font=("Arial", 10),
fg="blue"
)
instruksi_label.pack(pady=5)
# Fungsi Analisis
def analisis_bahan():
selected_items = []
for child in tree.get_children():
vals = tree.item(child, "values")
if vals[0] == "✔":
selected_items.append(vals)
if not selected_items:
messagebox.showwarning("Peringatan", "Pilih minimal 1 bahan untuk dianalisis!")
return
total_kalori = sum(float(item[2]) for item in selected_items)
total_protein = sum(float(item[3]) for item in selected_items)
total_lemak = sum(float(item[4]) for item in selected_items)
total_karbo = sum(float(item[5]) for item in selected_items)
total_vitamin = sum(float(item[6]) for item in selected_items)
hasil = (
f"Jumlah Bahan: {len(selected_items)}\n"
f"Total Kalori: {total_kalori} kkal\n"
f"Total Protein: {total_protein} g\n"
f"Total Lemak: {total_lemak} g\n"
f"Total Karbohidrat: {total_karbo} g\n"
f"Total Vitamin: {total_vitamin} IU"
)
messagebox.showinfo("Hasil Analisis", hasil)
# Tombol Analisis & Kembali
tk.Button(content_frame, text="Analisis", font=("Arial", 14),
bg="#4CAF50", fg="white", width=18, height=2,
command=analisis_bahan).pack(pady=10)
tk.Button(root_frame, text="Kembali", font=("Arial", 14),
bg="gray", fg="white", width=30, height=2,
command=lambda: show_menu_data_bahan_makanan(root_frame)).pack(pady=10)
Bersambung Ke: Konten Sub Menu "Ranking Bahan Berdasarkan Gizi Tertentu"
Comments
Post a Comment