MEMBUKA FILE DI PYTHON DAN MENJALANKAN ISINYA DENGAN PERINTAH EXEC (Part-2)
Agar lebih praktis, bagaimana kalau kita buat pada file CRUD_Gn_A_Trebel.py di bagian atas kode, kita buat perintah: from Modul_Mode_Progres import open_crud_gn_a_trebel. Dan atau mengimport fungsi yang lain yang terkait.
Baik, kita bisa membuat file `Modul_Mode_Progres.py` yang berisi fungsi-fungsi terkait, seperti `open_crud_gn_a_trebel`, dan kemudian mengimpornya di file `CRUD_Gn_A_Trebel.py`. Berikut adalah contoh bagaimana kita bisa memisahkan kode menjadi beberapa modul:
### File: Modul_Mode_Progres.py
```python
import tkinter as tk
def open_crud_gn_a_trebel():
# Fungsi yang membuka atau menangani CRUD pada Gn_A_Trebel
print("Membuka CRUD Gn_A_Trebel")
# Tambahkan fungsi-fungsi lain yang diperlukan
def open_crud_gn_biru():
print("Membuka CRUD Gn_Biru")
def open_crud_gn_cyan_bawah():
print("Membuka CRUD Gn_Cyan_Bawah")
def open_crud_gn_cyan_atas():
print("Membuka CRUD Gn_Cyan_Atas")
def open_crud_gn_a_bass():
print("Membuka CRUD Gn_A_Bass")
# Fungsi tambahan yang mungkin diperlukan
def clear_content_frame(frame):
for widget in frame.winfo_children():
widget.destroy()
def indicate(indicate_label, page_function, content_frame):
clear_indicators()
indicate_label.config(bg="#158aff")
page_function(content_frame)
def clear_indicators():
Gn_A_Trebel_indicate.config(bg="#c3c3c3")
Gn_Biru_indicate.config(bg="#c3c3c3")
Gn_Cyan_Atas_indicate.config(bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.config(bg="#c3c3c3")
Gn_A_Bass_indicate.config(bg="#c3c3c3")
```
### File: CRUD_Gn_A_Trebel.py
```python
import tkinter as tk
from Modul_Mode_Progres import (
open_crud_gn_a_trebel, open_crud_gn_biru, open_crud_gn_cyan_bawah,
open_crud_gn_cyan_atas, open_crud_gn_a_bass, clear_content_frame,
indicate, clear_indicators
)
root = tk.Tk()
root.geometry("800x600")
content_frame = tk.Frame(root, bg="#e2e2e2")
content_frame.pack(fill=tk.BOTH, expand=True)
bottom_frame = tk.Frame(root, bg="#f8f9fa", height=200)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
tk.Label(bottom_frame, text="Instruksi merangkai nada lagu \n dalam notasi angka, \n dengan Nada Penjuru Lagu \n (NPL) yang terprogram", font=("Helvetica", 10)).pack(side=tk.TOP, padx=10, pady=45)
tk.Label(bottom_frame, text="Progres Gugisan nada (Gn) \n ada di Progres-1, \n atau Progres-2, atau Progres-3 \n pada arah arus musik \n di mode Naik atau Turun", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=10)
tk.Label(bottom_frame, text="Arah arus musik (mode) Naik, \n dimulai dari Gn_A_Trebel, \n ke Gn_Biru, ke Gn_Cyan_Atas, \n ke Gn_A_Bass. \n Arah arus musik (mode) Turun, \n dimulai dari Gn_A_Bass \n ke Gn_Biru, ke Gn_Cyan_Bawah, \n ke Gn_A_Trebel.", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=8)
tk.Button(bottom_frame, text="Tombol 1", command=lambda: print("Tombol 1 diklik")).pack(side=tk.LEFT, padx=10, pady=105)
tk.Button(bottom_frame, text="MULAI", command=open_crud_gn_a_trebel, bg="green", fg="white").pack(side=tk.RIGHT, padx=10, pady=105)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
# Options Frame
options_frame = tk.Frame(root, bg="#c3c3c3")
Gn_A_Trebel_btn = tk.Button(options_frame, text="Gn_A_Trebel", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_A_Trebel_indicate, lambda: open_crud_gn_a_trebel(content_frame)))
Gn_A_Trebel_btn.place(x=3, y=50)
Gn_A_Trebel_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Trebel_indicate.place(x=2, y=55, width=5, height=45)
Gn_Biru_btn = tk.Button(options_frame, text="Gn_Biru", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_Biru_indicate, lambda: open_crud_gn_biru(content_frame)))
Gn_Biru_btn.place(x=3, y=100)
Gn_Biru_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Biru_indicate.place(x=2, y=105, width=5, height=45)
Gn_Cyan_Bawah_btn = tk.Button(options_frame, text="Gn_Cyan_Bawah", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_Cyan_Bawah_indicate, lambda: open_crud_gn_cyan_bawah(content_frame)))
Gn_Cyan_Bawah_btn.place(x=3, y=150)
Gn_Cyan_Bawah_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.place(x=2, y=155, width=5, height=45)
Gn_Cyan_Atas_btn = tk.Button(options_frame, text="Gn_Cyan_Atas", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_Cyan_Atas_indicate, lambda: open_crud_gn_cyan_atas(content_frame)))
Gn_Cyan_Atas_btn.place(x=3, y=200)
Gn_Cyan_Atas_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Atas_indicate.place(x=2, y=205, width=5, height=45)
Gn_A_Bass_btn = tk.Button(options_frame, text="Gn_A_Bass", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_A_Bass_indicate, lambda: open_crud_gn_a_bass(content_frame)))
Gn_A_Bass_btn.place(x=3, y=250)
Gn_A_Bass_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Bass_indicate.place(x=2, y=255, width=5, height=45)
options_frame.pack(side=tk.LEFT)
options_frame.pack_propagate(False)
options_frame.configure(width=153, height=300)
# Function to indicate which page is active
def indicate(indicate_label, page_function):
clear_indicators()
indicate_label.config(bg="#158aff")
page_function()
# Clear all indicators
def clear_indicators():
Gn_A_Trebel_indicate.config(bg="#c3c3c3")
Gn_Biru_indicate.config(bg="#c3c3c3")
Gn_Cyan_Atas_indicate.config(bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.config(bg="#c3c3c3")
Gn_A_Bass_indicate.config(bg="#c3c3c3")
# Start the main loop
root.mainloop()
```
Dengan cara ini, Anda memisahkan fungsionalitas ke dalam modul yang berbeda, sehingga kode lebih terorganisir dan mudah dikelola. File `Modul_Mode_Progres.py` berisi semua fungsi terkait yang dapat diimpor dan digunakan di berbagai bagian aplikasi.
Jadi menekan tombol MULAI bukan lagi dari file Modul_Mode_Progres.py, tapi sudah dari file CRUD_Gn_A_Trebel.py, bukankah begitu?. Tetapi Kenapa ketika kode file CRUD Gn_A_Trebel.py dieksekusi dan tombol MULAI ditekan, maka muncul Directory untuk memilih file, bukankah seharusnya langsung terbuka file CRUD Gn_A_Trebel.py, karena pada file Modul_Mode_Progres.py pada fungsi def open_crud_gn_a_trebel menggunakan perintah berikut:
def open_crud_gn_a_trebel():
filepath = "CRUD_Gn_A_Trebel.py"
try:
with open(filepath, 'r') as file:
exec(file.read(), globals())
messagebox.showinfo("Success", "File executed successfully")
except Exception as e:
messagebox.showerror("Error", f"Failed to execute file
: {e}")
Baik, saya mengerti sekarang. Jadi, kita ingin mengeksekusi kode dari file `CRUD_Gn_A_Trebel.py` saat tombol `MULAI` ditekan, tanpa membuka dialog pemilihan file. Berikut adalah langkah-langkah untuk memastikan hal ini bekerja dengan benar.
### File: Modul_Mode_Progres.py
```python
import tkinter as tk
from tkinter import messagebox
def open_crud_gn_a_trebel():
filepath = "CRUD_Gn_A_Trebel.py"
try:
with open(filepath, 'r') as file:
exec(file.read(), globals())
messagebox.showinfo("Success", "File executed successfully")
except Exception as e:
messagebox.showerror("Error", f"Failed to execute file: {e}")
# Tambahkan fungsi-fungsi lain yang diperlukan
def open_crud_gn_biru():
print("Membuka CRUD Gn_Biru")
def open_crud_gn_cyan_bawah():
print("Membuka CRUD Gn_Cyan_Bawah")
def open_crud_gn_cyan_atas():
print("Membuka CRUD Gn_Cyan_Atas")
def open_crud_gn_a_bass():
print("Membuka CRUD Gn_A_Bass")
# Fungsi tambahan yang mungkin diperlukan
def clear_content_frame(frame):
for widget in frame.winfo_children():
widget.destroy()
def indicate(indicate_label, page_function, content_frame):
clear_indicators()
indicate_label.config(bg="#158aff")
page_function(content_frame)
def clear_indicators():
Gn_A_Trebel_indicate.config(bg="#c3c3c3")
Gn_Biru_indicate.config(bg="#c3c3c3")
Gn_Cyan_Atas_indicate.config(bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.config(bg="#c3c3c3")
Gn_A_Bass_indicate.config(bg="#c3c3c3")
```
### File: CRUD_Gn_A_Trebel.py
```python
import tkinter as tk
from Modul_Mode_Progres import (
open_crud_gn_a_trebel, open_crud_gn_biru, open_crud_gn_cyan_bawah,
open_crud_gn_cyan_atas, open_crud_gn_a_bass, clear_content_frame,
indicate, clear_indicators
)
def main_app():
root = tk.Tk()
root.geometry("800x600")
content_frame = tk.Frame(root, bg="#e2e2e2")
content_frame.pack(fill=tk.BOTH, expand=True)
bottom_frame = tk.Frame(root, bg="#f8f9fa", height=200)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
tk.Label(bottom_frame, text="Instruksi merangkai nada lagu \n dalam notasi angka, \n dengan Nada Penjuru Lagu \n (NPL) yang terprogram", font=("Helvetica", 10)).pack(side=tk.TOP, padx=10, pady=45)
tk.Label(bottom_frame, text="Progres Gugisan nada (Gn) \n ada di Progres-1, \n atau Progres-2, atau Progres-3 \n pada arah arus musik \n di mode Naik atau Turun", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=10)
tk.Label(bottom_frame, text="Arah arus musik (mode) Naik, \n dimulai dari Gn_A_Trebel, \n ke Gn_Biru, ke Gn_Cyan_Atas, \n ke Gn_A_Bass. \n Arah arus musik (mode) Turun, \n dimulai dari Gn_A_Bass \n ke Gn_Biru, ke Gn_Cyan_Bawah, \n ke Gn_A_Trebel.", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=8)
tk.Button(bottom_frame, text="Tombol 1", command=lambda: print("Tombol 1 diklik")).pack(side=tk.LEFT, padx=10, pady=105)
tk.Button(bottom_frame, text="MULAI", command=open_crud_gn_a_trebel, bg="green", fg="white").pack(side=tk.RIGHT, padx=10, pady=105)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
# Options Frame
options_frame = tk.Frame(root, bg="#c3c3c3")
Gn_A_Trebel_btn = tk.Button(options_frame, text="Gn_A_Trebel", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_A_Trebel_indicate, open_crud_gn_a_trebel, content_frame))
Gn_A_Trebel_btn.place(x=3, y=50)
Gn_A_Trebel_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Trebel_indicate.place(x=2, y=55, width=5, height=45)
Gn_Biru_btn = tk.Button(options_frame, text="Gn_Biru", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_Biru_indicate, open_crud_gn_biru, content_frame))
Gn_Biru_btn.place(x=3, y=100)
Gn_Biru_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Biru_indicate.place(x=2, y=105, width=5, height=45)
Gn_Cyan_Bawah_btn = tk.Button(options_frame, text="Gn_Cyan_Bawah", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_Cyan_Bawah_indicate, open_crud_gn_cyan_bawah, content_frame))
Gn_Cyan_Bawah_btn.place(x=3, y=150)
Gn_Cyan_Bawah_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.place(x=2, y=155, width=5, height=45)
Gn_Cyan_Atas_btn = tk.Button(options_frame, text="Gn_Cyan_Atas", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_Cyan_Atas_indicate, open_crud_gn_cyan_atas, content_frame))
Gn_Cyan_Atas_btn.place(x=3, y=200)
Gn_Cyan_Atas_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Atas_indicate.place(x=2, y=205, width=5, height=45)
Gn_A_Bass_btn = tk.Button(options_frame, text="Gn_A_Bass", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: indicate(Gn_A_Bass_indicate, open_crud_gn_a_bass, content_frame))
Gn_A_Bass_btn.place(x=3, y=250)
Gn_A_Bass_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Bass_indicate.place(x=2, y=255, width=5, height=45)
options_frame.pack(side=tk.LEFT)
options_frame.pack_propagate(False)
options_frame.configure(width=153, height=300)
# Function to indicate which page is active
def indicate(indicate_label, page_function, content_frame):
clear_indicators()
indicate_label.config(bg="#158aff")
page_function()
# Clear all indicators
def clear_indicators():
Gn_A_Trebel_indicate.config(bg="#c3c3c3")
Gn_Biru_indicate.config(bg="#c3c3c3")
Gn_Cyan_Atas_indicate.config(bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.config(bg="#c3c3c3")
Gn_A_Bass_indicate.config(bg="#c3c3c3")
# Start the main loop
root.mainloop()
if __name__ == "__main__":
main_app()
```
### Penjelasan
1. **`Modul_Mode_Progres.py`**: File ini berisi fungsi `open_crud_gn_a_trebel` yang mengeksekusi file `CRUD_Gn_A_Trebel.py` ketika dipanggil. Fungsi ini menggunakan `exec` untuk mengeksekusi kode dari file lain.
2. **`CRUD_Gn_A_Trebel.py`**: File ini berisi fungsi `main_app` yang mengatur dan menjalankan aplikasi Tkinter utama. Tombol `MULAI` di dalam `main_app` memanggil `open_crud_gn_a_trebel` dari `Modul_Mode_Progres.py`, yang kemudian mengeksekusi kembali file ini jika diperlukan.
Dengan demikian, ketika Anda menekan tombol `MULAI`, seharusnya tidak membuka dialog pemilihan file, tetapi langsung mengeksekusi kode yang ada di `CRUD_Gn_A_Trebel.py`.
File CRUD_Gn_A_Trebel.py sudah langsung terbuka ketika menekan tombol MULAI. Tapi kenapa setelah melakukan CRUD, menginput data maka selalu kembali ke halaman pertama yang tombol MULAI tersebut berada
Tampaknya setelah melakukan operasi CRUD, aplikasi kembali ke kondisi awal di mana tombol `MULAI` ada di halaman pertama. Untuk memastikan aplikasi tetap berada di halaman yang tepat setelah operasi CRUD, kita perlu menjaga state aplikasi dan memastikan bahwa tampilan halaman tidak kembali ke kondisi awal setiap kali operasi dilakukan.
Kita bisa memperbaiki ini dengan memastikan bahwa setelah operasi CRUD dilakukan, aplikasi tetap berada pada halaman yang sesuai.
### Penjelasan Solusi
1. **Menjaga State Halaman Aktif**: Tambahkan variabel global atau state management untuk menjaga halaman mana yang sedang aktif.
2. **Menyimpan State Halaman**: Setiap kali operasi CRUD dilakukan, pastikan state halaman disimpan dan setelah operasi selesai, tampilkan kembali halaman yang sesuai.
Berikut adalah contoh implementasi yang memperbaiki masalah ini:
### File: Modul_Mode_Progres.py
Pastikan tidak ada perubahan yang menyebabkan halaman kembali ke kondisi awal. Tidak ada modifikasi yang perlu dilakukan di file ini.
### File: CRUD_Gn_A_Trebel.py
Tambahkan variabel global untuk menyimpan state halaman aktif dan modifikasi fungsi `indicate` serta CRUD functions untuk menjaga state halaman.
```python
import tkinter as tk
from Modul_Mode_Progres import (
open_crud_gn_a_trebel, open_crud_gn_biru, open_crud_gn_cyan_bawah,
open_crud_gn_cyan_atas, open_crud_gn_a_bass, clear_content_frame,
indicate, clear_indicators
)
active_page = None # Variabel global untuk menyimpan halaman aktif
def main_app():
global active_page
root = tk.Tk()
root.geometry("800x600")
content_frame = tk.Frame(root, bg="#e2e2e2")
content_frame.pack(fill=tk.BOTH, expand=True)
bottom_frame = tk.Frame(root, bg="#f8f9fa", height=200)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
tk.Label(bottom_frame, text="Instruksi merangkai nada lagu \n dalam notasi angka, \n dengan Nada Penjuru Lagu \n (NPL) yang terprogram", font=("Helvetica", 10)).pack(side=tk.TOP, padx=10, pady=45)
tk.Label(bottom_frame, text="Progres Gugisan nada (Gn) \n ada di Progres-1, \n atau Progres-2, atau Progres-3 \n pada arah arus musik \n di mode Naik atau Turun", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=10)
tk.Label(bottom_frame, text="Arah arus musik (mode) Naik, \n dimulai dari Gn_A_Trebel, \n ke Gn_Biru, ke Gn_Cyan_Atas, \n ke Gn_A_Bass. \n Arah arus musik (mode) Turun, \n dimulai dari Gn_A_Bass \n ke Gn_Biru, ke Gn_Cyan_Bawah, \n ke Gn_A_Trebel.", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=8)
tk.Button(bottom_frame, text="Tombol 1", command=lambda: print("Tombol 1 diklik")).pack(side=tk.LEFT, padx=10, pady=105)
tk.Button(bottom_frame, text="MULAI", command=open_crud_gn_a_trebel, bg="green", fg="white").pack(side=tk.RIGHT, padx=10, pady=105)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
# Options Frame
options_frame = tk.Frame(root, bg="#c3c3c3")
Gn_A_Trebel_btn = tk.Button(options_frame, text="Gn_A_Trebel", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_A_Trebel", content_frame))
Gn_A_Trebel_btn.place(x=3, y=50)
Gn_A_Trebel_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Trebel_indicate.place(x=2, y=55, width=5, height=45)
Gn_Biru_btn = tk.Button(options_frame, text="Gn_Biru", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_Biru", content_frame))
Gn_Biru_btn.place(x=3, y=100)
Gn_Biru_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Biru_indicate.place(x=2, y=105, width=5, height=45)
Gn_Cyan_Bawah_btn = tk.Button(options_frame, text="Gn_Cyan_Bawah", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_Cyan_Bawah", content_frame))
Gn_Cyan_Bawah_btn.place(x=3, y=150)
Gn_Cyan_Bawah_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.place(x=2, y=155, width=5, height=45)
Gn_Cyan_Atas_btn = tk.Button(options_frame, text="Gn_Cyan_Atas", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_Cyan_Atas", content_frame))
Gn_Cyan_Atas_btn.place(x=3, y=200)
Gn_Cyan_Atas_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Atas_indicate.place(x=2, y=205, width=5, height=45)
Gn_A_Bass_btn = tk.Button(options_frame, text="Gn_A_Bass", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_A_Bass", content_frame))
Gn_A_Bass_btn.place(x=3, y=250)
Gn_A_Bass_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Bass_indicate.place(x=2, y=255, width=5, height=45)
options_frame.pack(side=tk.LEFT)
options_frame.pack_propagate(False)
options_frame.configure(width=153, height=300)
def switch_page(page, content_frame):
global active_page
active_page = page
indicate_page(page, content_frame)
def indicate_page(page, content_frame):
clear_indicators()
if page == "Gn_A_Trebel":
Gn_A_Trebel_indicate.config(bg="#158aff")
open_crud_gn_a_trebel()
elif page == "Gn_Biru":
Gn_Biru_indicate.config(bg="#158aff")
open_crud_gn_biru()
elif page == "Gn_Cyan_Bawah":
Gn_Cyan_Bawah_indicate.config(bg="#158aff")
open_crud_gn_cyan_bawah()
elif page == "Gn_Cyan_Atas":
Gn_Cyan_Atas_indicate.config(bg="#158aff")
open_crud_gn_cyan_atas()
elif page == "Gn_A_Bass":
Gn_A_Bass_indicate.config(bg="#158aff")
open_crud_gn_a_bass()
def clear_indicators():
Gn_A_Trebel_indicate.config(bg="#c3c3c3")
Gn_Biru_indicate.config(bg="#c3c3c3")
Gn_Cyan_Atas_indicate.config(bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.config(bg="#c3c3c3")
Gn_A_Bass_indicate.config(bg="#c3c3c3")
if active_page:
indicate_page(active_page, content_frame)
root.mainloop()
if __name__ == "__main__":
main_app()
```
### Penjelasan
1. **Variabel `active_page`**: Digunakan untuk menyimpan halaman aktif saat ini.
2. **Fungsi `switch_page`**: Mengubah halaman dan memperbarui indikator halaman aktif.
3. **Fungsi `indicate_page`**: Menunjukkan halaman aktif berdasarkan nilai `active_page`.
4. **Menjaga State Halaman**: Pada awal aplikasi, jika `active_page` tidak kosong, aplikasi akan menunjukkan halaman yang sesuai dengan `active_page`.
Dengan perubahan ini, setelah operasi CRUD dilakukan, aplikasi akan tetap berada pada halaman yang sesuai tanpa kembali ke kondisi awal.
Setelah menginput data, masih juga kembali ke halaman pertama dimana tombol MULAI berada tersebut.
Jika aplikasi masih kembali ke halaman awal setelah input data, kita perlu memastikan bahwa fungsi CRUD yang dieksekusi tidak menyebabkan aplikasi kembali ke halaman awal. Salah satu cara untuk memastikan ini adalah dengan memeriksa bagaimana eksekusi kode dilakukan dalam fungsi `open_crud_gn_a_trebel`.
### Penjelasan dan Modifikasi
1. **Hindari Reset State**: Pastikan eksekusi kode dalam `open_crud_gn_a_trebel` tidak melakukan reset terhadap state atau frame yang ada.
2. **Memastikan Eksekusi di Halaman yang Sama**: Setelah operasi CRUD dilakukan, pastikan frame yang sedang aktif tetap dipertahankan dan tidak di-reset.
### File: Modul_Mode_Progres.py
Tambahkan logika untuk menjaga halaman aktif tetap aktif setelah eksekusi operasi CRUD.
```python
import tkinter as tk
from tkinter import messagebox
def open_crud_gn_a_trebel():
filepath = "CRUD_Gn_A_Trebel.py"
try:
with open(filepath, 'r') as file:
exec(file.read(), globals())
messagebox.showinfo("Success", "File executed successfully")
except Exception as e:
messagebox.showerror("Error", f"Failed to execute file: {e}")
def open_crud_gn_biru():
# Implementasikan logika yang sama untuk halaman lain jika perlu
pass
# Implementasikan fungsi-fungsi open_crud lainnya serupa jika diperlukan
def clear_content_frame(frame):
for widget in frame.winfo_children():
widget.destroy()
def indicate(page, frame):
clear_content_frame(frame)
if page == "Gn_A_Trebel":
open_crud_gn_a_trebel()
elif page == "Gn_Biru":
open_crud_gn_biru()
# Tambahkan logika untuk halaman lainnya jika diperlukan
def clear_indicators():
# Implementasikan logika jika ada indikator yang perlu di-reset
pass
```
### File: CRUD_Gn_A_Trebel.py
Tambahkan logika untuk menjaga state halaman setelah operasi CRUD.
```python
import tkinter as tk
from Modul_Mode_Progres import indicate, clear_indicators, open_crud_gn_a_trebel, open_crud_gn_biru, open_crud_gn_cyan_bawah, open_crud_gn_cyan_atas, open_crud_gn_a_bass
active_page = None # Variabel global untuk menyimpan halaman aktif
def main_app():
global active_page
root = tk.Tk()
root.geometry("800x600")
content_frame = tk.Frame(root, bg="#e2e2e2")
content_frame.pack(fill=tk.BOTH, expand=True)
bottom_frame = tk.Frame(root, bg="#f8f9fa", height=200)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
tk.Label(bottom_frame, text="Instruksi merangkai nada lagu \n dalam notasi angka, \n dengan Nada Penjuru Lagu \n (NPL) yang terprogram", font=("Helvetica", 10)).pack(side=tk.TOP, padx=10, pady=45)
tk.Label(bottom_frame, text="Progres Gugisan nada (Gn) \n ada di Progres-1, \n atau Progres-2, atau Progres-3 \n pada arah arus musik \n di mode Naik atau Turun", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=10)
tk.Label(bottom_frame, text="Arah arus musik (mode) Naik, \n dimulai dari Gn_A_Trebel, \n ke Gn_Biru, ke Gn_Cyan_Atas, \n ke Gn_A_Bass. \n Arah arus musik (mode) Turun, \n dimulai dari Gn_A_Bass \n ke Gn_Biru, ke Gn_Cyan_Bawah, \n ke Gn_A_Trebel.", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=8)
tk.Button(bottom_frame, text="Tombol 1", command=lambda: print("Tombol 1 diklik")).pack(side=tk.LEFT, padx=10, pady=105)
tk.Button(bottom_frame, text="MULAI", command=open_crud_gn_a_trebel, bg="green", fg="white").pack(side=tk.RIGHT, padx=10, pady=105)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
options_frame = tk.Frame(root, bg="#c3c3c3")
Gn_A_Trebel_btn = tk.Button(options_frame, text="Gn_A_Trebel", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_A_Trebel", content_frame))
Gn_A_Trebel_btn.place(x=3, y=50)
Gn_A_Trebel_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Trebel_indicate.place(x=2, y=55, width=5, height=45)
Gn_Biru_btn = tk.Button(options_frame, text="Gn_Biru", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_Biru", content_frame))
Gn_Biru_btn.place(x=3, y=100)
Gn_Biru_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Biru_indicate.place(x=2, y=105, width=5, height=45)
Gn_Cyan_Bawah_btn = tk.Button(options_frame, text="Gn_Cyan_Bawah", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_Cyan_Bawah", content_frame))
Gn_Cyan_Bawah_btn.place(x=3, y=150)
Gn_Cyan_Bawah_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.place(x=2, y=155, width=5, height=45)
Gn_Cyan_Atas_btn = tk.Button(options_frame, text="Gn_Cyan_Atas", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_Cyan_Atas", content_frame))
Gn_Cyan_Atas_btn.place(x=3, y=200)
Gn_Cyan_Atas_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Atas_indicate.place(x=2, y=205, width=5, height=45)
Gn_A_Bass_btn = tk.Button(options_frame, text="Gn_A_Bass", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_A_Bass", content_frame))
Gn_A_Bass_btn.place(x=3, y=250)
Gn_A_Bass_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Bass_indicate.place(x=2, y=255, width=5, height=45)
options_frame.pack(side=tk.LEFT)
options_frame.pack_propagate(False)
options_frame.configure(width=153, height=300)
def switch_page(page, content_frame):
global active_page
active_page = page
indicate_page(page, content_frame)
def indicate_page(page, content_frame):
clear_indicators()
if page == "Gn_A_Trebel":
Gn_A_Trebel_indicate.config(bg="#158aff")
open_crud_gn_a_trebel()
elif page == "Gn_Biru":
Gn_Biru_indicate.config(bg="#158aff")
open_crud_gn_biru()
elif page == "Gn_Cyan_Bawah":
Gn_Cyan_Bawah_indicate.config(bg="#158aff")
open_crud_gn_cyan_bawah()
elif page == "Gn_Cyan_Atas":
Gn_Cyan_Atas_indicate.config(bg="#158aff")
open_crud_gn_cyan_atas()
elif page == "Gn_A_Bass":
Gn_A_Bass_indicate.config(bg="#158aff")
open_crud_gn_a_bass()
def clear_indicators():
Gn_A_Trebel_indicate.config(bg="#c3c3c3")
Gn_Biru_indicate.config(bg="#c3c3c3")
Gn_Cyan_Atas_indicate.config(bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.config(bg="#c3c3c3")
Gn_A_Bass_indicate.config(bg="#c3c3c3")
if active_page:
indicate_page(active_page, content_frame)
root.mainloop()
if __name__ == "__main__":
main_app()
```
### Penjelasan
1. **Menjaga State Halaman Aktif**: Memastikan `active_page` tetap diperbarui saat halaman berubah.
2. **Fungsi `switch_page` dan `indicate_page`**: Mengatur halaman mana yang aktif dan menunjukkan halaman tersebut berdasarkan state.
3. **Eksekusi CRUD**: Mengatur eksekusi operasi CRUD di halaman yang relevan dan memastikan halaman tersebut tetap aktif setelah operasi selesai. Ini dilakukan dengan memastikan `active_page` tetap diperbarui dan frame yang relevan tetap aktif tanpa reset setelah operasi CRUD.
### Memastikan Halaman Tetap Aktif Setelah CRUD
Untuk memastikan bahwa halaman tetap aktif setelah operasi CRUD dilakukan, berikut beberapa langkah yang perlu diperhatikan:
1. **Perbarui `active_page`**: Pastikan `active_page` diperbarui setiap kali halaman berubah.
2. **Tidak Mengatur Ulang Frame**: Pastikan operasi CRUD tidak mengatur ulang atau mereset frame yang ada.
3. **Indikator Halaman Aktif**: Gunakan indikator visual seperti mengubah warna label atau tombol untuk menunjukkan halaman mana yang aktif.
Dengan menggunakan pendekatan ini, ketika operasi CRUD dijalankan, halaman tetap berada di posisi yang sama tanpa kembali ke halaman awal. Berikut adalah modifikasi kode pada fungsi `open_crud_gn_a_trebel` dan fungsi terkait lainnya di `Modul_Mode_Progres.py` untuk memastikan hal tersebut.
### File: Modul_Mode_Progres.py (Update)
```python
import tkinter as tk
from tkinter import messagebox
active_page = None # Menyimpan halaman aktif
def open_crud_gn_a_trebel():
filepath = "CRUD_Gn_A_Trebel.py"
try:
with open(filepath, 'r') as file:
exec(file.read(), globals())
messagebox.showinfo("Success", "File executed successfully")
except Exception as e:
messagebox.showerror("Error", f"Failed to execute file: {e}")
def open_crud_gn_biru():
# Implementasikan logika yang sama untuk halaman lain jika perlu
pass
def clear_content_frame(frame):
for widget in frame.winfo_children():
widget.destroy()
def indicate(page, frame):
global active_page
active_page = page
clear_content_frame(frame)
if page == "Gn_A_Trebel":
open_crud_gn_a_trebel()
elif page == "Gn_Biru":
open_crud_gn_biru()
# Tambahkan logika untuk halaman lainnya jika diperlukan
def clear_indicators():
# Implementasikan logika jika ada indikator yang perlu di-reset
pass
```
### File: CRUD_Gn_A_Trebel.py (Update)
```python
import tkinter as tk
from Modul_Mode_Progres import indicate, clear_indicators, open_crud_gn_a_trebel, open_crud_gn_biru, open_crud_gn_cyan_bawah, open_crud_gn_cyan_atas, open_crud_gn_a_bass
active_page = None # Variabel global untuk menyimpan halaman aktif
def main_app():
global active_page
root = tk.Tk()
root.geometry("800x600")
content_frame = tk.Frame(root, bg="#e2e2e2")
content_frame.pack(fill=tk.BOTH, expand=True)
bottom_frame = tk.Frame(root, bg="#f8f9fa", height=200)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
tk.Label(bottom_frame, text="Instruksi merangkai nada lagu \n dalam notasi angka, \n dengan Nada Penjuru Lagu \n (NPL) yang terprogram", font=("Helvetica", 10)).pack(side=tk.TOP, padx=10, pady=45)
tk.Label(bottom_frame, text="Progres Gugisan nada (Gn) \n ada di Progres-1, \n atau Progres-2, atau Progres-3 \n pada arah arus musik \n di mode Naik atau Turun", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=10)
tk.Label(bottom_frame, text="Arah arus musik (mode) Naik, \n dimulai dari Gn_A_Trebel, \n ke Gn_Biru, ke Gn_Cyan_Atas, \n ke Gn_A_Bass. \n Arah arus musik (mode) Turun, \n dimulai dari Gn_A_Bass \n ke Gn_Biru, ke Gn_Cyan_Bawah, \n ke Gn_A_Trebel.", font=("Helvetica", 9)).pack(side=tk.TOP, padx=10, pady=8)
tk.Button(bottom_frame, text="Tombol 1", command=lambda: print("Tombol 1 diklik")).pack(side=tk.LEFT, padx=10, pady=105)
tk.Button(bottom_frame, text="MULAI", command=open_crud_gn_a_trebel, bg="green", fg="white").pack(side=tk.RIGHT, padx=10, pady=105)
options_frame = tk.Frame(root, bg="#c3c3c3")
Gn_A_Trebel_btn = tk.Button(options_frame, text="Gn_A_Trebel", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_A_Trebel", content_frame))
Gn_A_Trebel_btn.place(x=3, y=50)
Gn_A_Trebel_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Trebel_indicate.place(x=2, y=55, width=5, height=45)
Gn_Biru_btn = tk.Button(options_frame, text="Gn_Biru", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_Biru", content_frame))
Gn_Biru_btn.place(x=3, y=100)
Gn_Biru_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Biru_indicate.place(x=2, y=105, width=5, height=45)
Gn_Cyan_Bawah_btn = tk.Button(options_frame, text="Gn_Cyan_Bawah", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_Cyan_Bawah", content_frame))
Gn_Cyan_Bawah_btn.place(x=3, y=150)
Gn_Cyan_Bawah_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.place(x=2, y=155, width=5, height=45)
Gn_Cyan_Atas_btn = tk.Button(options_frame, text="Gn_Cyan_Atas", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_Cyan_Atas", content_frame))
Gn_Cyan_Atas_btn.place(x=3, y=200)
Gn_Cyan_Atas_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_Cyan_Atas_indicate.place(x=2, y=205, width=5, height=45)
Gn_A_Bass_btn = tk.Button(options_frame, text="Gn_A_Bass", font=("bold", 7), fg="#158aff", bd=0, bg="#c3c3c3", command=lambda: switch_page("Gn_A_Bass", content_frame))
Gn_A_Bass_btn.place(x=3, y=250)
Gn_A_Bass_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")
Gn_A_Bass_indicate.place(x=2, y=255, width=5, height=45)
options_frame.pack(side=tk.LEFT)
options_frame.pack_propagate(False)
options_frame.configure(width=153, height=300)
def switch_page(page, content_frame):
global active_page
active_page = page
indicate_page(page, content_frame)
def indicate_page(page, content_frame):
clear_indicators()
if page == "Gn_A_Trebel":
Gn_A_Trebel_indicate.config(bg="#158aff")
open_crud_gn_a_trebel()
elif page == "Gn_Biru":
Gn_Biru_indicate.config(bg="#158aff")
open_crud_gn_biru()
elif page == "Gn_Cyan_Bawah":
Gn_Cyan_Bawah_indicate.config(bg="#158aff")
open_crud_gn_cyan_bawah()
elif page == "Gn_Cyan_Atas":
Gn_Cyan_Atas_indicate.config(bg="#158aff")
open_crud_gn_cyan_atas()
elif page == "Gn_A_Bass":
Gn_A_Bass_indicate.config(bg="#158aff")
open_crud_gn_a_bass()
def clear_indicators():
Gn_A_Trebel_indicate.config(bg="#c3c3c3")
Gn_Biru_indicate.config(bg="#c3c3c3")
Gn_Cyan_Atas_indicate.config(bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.config(bg="#c3c3c3")
Gn_A_Bass_indicate.config(bg="#c3c3c3")
if active_page:
indicate_page(active_page, content_frame)
root.mainloop()
if __name__ == "__main__":
main_app()
```
### Penjelasan Kode
Kode di atas terdiri dari dua bagian utama: `Modul_Mode_Progres.py` dan `CRUD_Gn_A_Trebel.py`. Berikut adalah penjelasan masing-masing bagian:
### File: Modul_Mode_Progres.py
File ini berisi fungsi-fungsi utama yang digunakan untuk membuka halaman CRUD dan mengatur halaman yang aktif.
1. **Global Variable `active_page`**:
```python
active_page = None # Menyimpan halaman aktif
```
Variabel global `active_page` digunakan untuk menyimpan informasi tentang halaman mana yang sedang aktif.
2. **Fungsi `open_crud_gn_a_trebel`**:
```python
def open_crud_gn_a_trebel():
filepath = "CRUD_Gn_A_Trebel.py"
try:
with open(filepath, 'r') as file:
exec(file.read(), globals())
messagebox.showinfo("Success", "File executed successfully")
except Exception as e:
messagebox.showerror("Error", f"Failed to execute file: {e}")
```
Fungsi ini membuka dan menjalankan file `CRUD_Gn_A_Trebel.py`.
3. **Fungsi `clear_content_frame`**:
```python
def clear_content_frame(frame):
for widget in frame.winfo_children():
widget.destroy()
```
Fungsi ini membersihkan semua widget yang ada di dalam frame yang diberikan.
4. **Fungsi `indicate`**:
```python
def indicate(page, frame):
global active_page
active_page = page
clear_content_frame(frame)
if page == "Gn_A_Trebel":
open_crud_gn_a_trebel()
elif page == "Gn_Biru":
open_crud_gn_biru()
# Tambahkan logika untuk halaman lainnya jika diperlukan
```
Fungsi ini mengatur halaman yang aktif berdasarkan parameter `page` yang diberikan.
5. **Fungsi `clear_indicators`**:
```python
def clear_indicators():
# Implementasikan logika jika ada indikator yang perlu di-reset
pass
```
Fungsi ini digunakan untuk mengatur ulang indikator halaman.
### File: CRUD_Gn_A_Trebel.py
File ini berisi implementasi GUI utama dan logika untuk mengatur halaman CRUD.
1. **Global Variable `active_page`**:
```python
active_page = None # Variabel global untuk menyimpan halaman aktif
```
Sama seperti di `Modul_Mode_Progres.py`, variabel ini digunakan untuk menyimpan halaman aktif.
2. **Fungsi `main_app`**:
```python
def main_app():
global active_page
root = tk.Tk()
root.geometry("800x600")
```
Fungsi utama yang mengatur GUI aplikasi.
3. **Frame Utama**:
```python
content_frame = tk.Frame(root, bg="#e2e2e2")
content_frame.pack(fill=tk.BOTH, expand=True)
```
Frame utama untuk menampilkan konten.
4. **Frame Bawah**:
```python
bottom_frame = tk.Frame(root, bg="#f8f9fa", height=200)
bottom_frame.pack(side=tk.BOTTOM, fill=tk.X)
```
Frame bawah yang berisi label dan tombol.
5. **Tombol `MULAI`**:
```python
tk.Button(bottom_frame, text="MULAI", command=open_crud_gn_a_trebel, bg="green", fg="white").pack(side=tk.RIGHT, padx=10, pady=105)
```
Tombol yang digunakan untuk memulai halaman CRUD `Gn_A_Trebel`.
6. **Frame Opsi**:
```python
options_frame = tk.Frame(root, bg="#c3c3c3")
options_frame.pack(side=tk.LEFT)
options_frame.pack_propagate(False)
options_frame.configure(width=153, height=300)
```
Frame yang berisi tombol navigasi untuk halaman-halaman CRUD.
7. **Fungsi `switch_page`**:
```python
def switch_page(page, content_frame):
global active_page
active_page = page
indicate_page(page, content_frame)
```
Fungsi ini digunakan untuk mengubah halaman berdasarkan parameter `page` yang diberikan.
8. **Fungsi `indicate_page`**:
```python
def indicate_page(page, content_frame):
clear_indicators()
if page == "Gn_A_Trebel":
Gn_A_Trebel_indicate.config(bg="#158aff")
open_crud_gn_a_trebel()
elif page == "Gn_Biru":
Gn_Biru_indicate.config(bg="#158aff")
open_crud_gn_biru()
# Tambahkan logika untuk halaman lainnya jika diperlukan
```
Fungsi ini menampilkan halaman yang sesuai dan mengatur indikator halaman aktif.
9. **Fungsi `clear_indicators`**:
```python
def clear_indicators():
Gn_A_Trebel_indicate.config(bg="#c3c3c3")
Gn_Biru_indicate.config(bg="#c3c3c3")
Gn_Cyan_Atas_indicate.config(bg="#c3c3c3")
Gn_Cyan_Bawah_indicate.config(bg="#c3c3c3")
Gn_A_Bass_indicate.config(bg="#c3c3c3")
```
Fungsi ini mengatur ulang warna indikator halaman.
10. **Inisialisasi Halaman Aktif**:
```python
if active_page:
indicate_page(active_page, content_frame)
```
11. **Menjalankan Aplikasi**:
```python
root.mainloop()
```
### Kesimpulan
Dengan memastikan bahwa variabel `active_page` selalu diperbarui dan frame tidak di-reset setelah operasi CRUD, halaman aktif akan tetap aktif dan tidak kembali ke halaman awal setelah input data atau operasi CRUD lainnya.
Cara membuka file secara langsung tanpa dialog file, tanpa menanyakan direktori file.
# Fungsi untuk membuka file CRUD_Gn_A_Bass.py
active_page = None # Menyimpan halaman aktif
def open_crud_gn_a_bass():
filepath = "CRUD_Gn_A_Bass.py"
try:
with open(filepath, 'r') as file:
exec(file.read(), globals())
messagebox.showinfo("Success", "File executed successfully")
except Exception as e:
messagebox.showerror("Error", f"Failed to execute file: {e}")
# Labels and Buttons in Bottom Frame
tk.Button(bottom_frame, text="MULAI", command=open_crud_gn_a_bass, bg="green", fg="white").pack(side=tk.RIGHT, padx=10, pady=105)
Komentar
Posting Komentar
This Message