Langsung ke konten utama

FUNGSI PENGGULIRAN (SCROLLBAR) KE SEGALA ARAH PADA SEMUA ELEMEN GUI DAN FUNGSI PADA KODE

FUNGSI PENGGULIRAN (SCROLLBAR) KE SEGALA ARAH PADA SEMUA ELEMEN GUI DAN FUNGSI PADA KODE


Tolong tambahkan fungsi pengguliran ke segala arah pada kode berikut ini sehingga semua elemen GUI dan semua fungsi pada kode berada di dalam scrollbar_frame. Kode ini bersambung, dan sambungan kode akan saya berikan pada chat berikutnya. Ini kodenya:

import tkinter as tk

from tkinter import ttk

import sqlite3

from tkinter import messagebox

from tkinter import filedialog

from tkinter import Tk, Label, Entry, Button, Frame, StringVar

import subprocess

import os

import logging


# Initialize logging

logging.basicConfig(level=logging.INFO)


# Initialize the main window

root = tk.Tk()

root.geometry("690x1390")

root.title("Arah Arus Musik")    


# Head Frame

head_frame = tk.Frame(root, bg="#158aff", highlightbackground="white", highlightthickness=1)

head_frame.place()


# Content Frame

content_frame = tk.Frame(root)

content_frame.pack()


# Koneksi ke database dan inisialisasi tabel jika belum ada

def init_db():

    conn = sqlite3.connect('DATAMUSIK.db')

    c = conn.cursor()

    c.execute('''

        CREATE TABLE IF NOT EXISTS Gn_Cyan_Bawah (

            ID INTEGER PRIMARY KEY,

            Level_R TEXT,

            Bass INT,            

            Trebel_Biasa INT,

            Trebel_Aneh INT

        )

    ''')

    c.execute('''

        CREATE TABLE IF NOT EXISTS Sub_Gn_Cyan_Bawah(

            Sub_ID INTEGER PRIMARY KEY,

            Level_D TEXT,

            Bass INT,

            Trebel_Biasa INT,

            Trebel_Aneh INT    

        )

    ''')

    conn.commit()

    conn.close()


# Function to clear content frame

def clear_content_frame():

    for widget in content_frame.winfo_children():

        widget.destroy()                                                                                

# Function to switch modes and update pages

def switch_mode(progres, mode):

    if mode[progres - 1] == "naik":

        mode[progres - 1] = "turun"

        setup_turun_mode(progres)

    else:

        mode[progres - 1] = "naik"

        setup_naik_mode(progres)

        

# Options Frame

options_frame = tk.Frame(root, bg="#c3c3c3") 


# Current mode for each toggle button

current_mode = ['naik', 'naik', 'naik']

toggle_btns = []

indicator_labels = []

pages = [

    ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass'],

    ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass'],

    ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

]                                                

                                     

# Function to toggle menus

def toggle_menu(progres, mode):

    if mode[progres - 1] == 'naik':

        mode[progres - 1] = 'turun'

        toggle_btns[progres - 1].config(text="X _ T")

        pages[progres - 1] = ['Gn_A_Bass', 'Gn_Biru', 'Gn_Cyan_Bawah', 'Gn_A_Trebel']

        indicator_labels[progres - 1].config(text="Turun")

    else:

        mode[progres - 1] = 'naik'

        toggle_btns[progres - 1].config(text="☰ _ N")

        pages[progres - 1] = ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

        indicator_labels[progres - 1].config(text="Naik")

    

    update_options_frame(progres)

    display_pages(progres)

    

# Function to display pages

def display_pages(progres):

    for widget in content_frame.winfo_children():

        widget.destroy()


    display_gn_cyan_bawah_page()


# Function to display default page

def display_gn_cyan_bawah_page():

    clear_content_frame()

    tk.Label(content_frame, text="Ini adalah Halaman Gn_Cyan_Bawah", font=("Helvetica", 10)).pack()    

              

# Function to setup "Naik" mode

def setup_naik_mode(progres):

    if progres == 1:

        pages[0] = ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

    elif progres == 2:

        pages[1] = ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

    elif progres == 3:

        pages[2] = ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

    

# Function to setup "Turun" mode

def setup_turun_mode(progres):

    if progres == 1:

        pages[0] = ['Gn_A_Bass', 'Gn_Biru', 'Gn_Cyan_Bawah', 'Gn_A_Trebel']

    elif progres == 2:

        pages[1] = ['Gn_A_Bass', 'Gn_Biru', 'Gn_Cyan_Bawah', 'Gn_A_Trebel']

    elif progres == 3:

        pages[2] = ['Gn_A_Bass', 'Gn_Biru', 'Gn_Cyan_Bawah', 'Gn_A_Trebel']

                 

# Toggle Button 1

toggle_btn1 = tk.Button(head_frame, text="☰ _ P 1", bg="#158aff", font=("bold", 6), fg="white", bd=0, activebackground="#158aff", activeforeground="white", command=lambda: toggle_menu(1, current_mode))

toggle_btn1.pack(side=tk.LEFT)

toggle_btn1.place(x=5, y=20)

toggle_btns.append(toggle_btn1)


title_lb1 = tk.Label(head_frame, text="Progres-1", bg="#158aff", fg="white", font=("bold", 7))

title_lb1.pack(side=tk.LEFT)

title_lb1.place(x=108, y=11)


indicator_label1 = tk.Label(head_frame, text="Naik", bg="#158aff", fg="yellow", font=("bold", 8))

indicator_label1.pack(side=tk.LEFT)

indicator_label1.place(x=127, y=55)

indicator_labels.append(indicator_label1)


# Toggle Button 2

toggle_btn2 = tk.Button(head_frame, text="☰ _ P 2", bg="#158aff", font=("bold", 6), fg="white", bd=0, activebackground="#158aff", activeforeground="white", command=lambda: toggle_menu(2, current_mode))

toggle_btn2.pack(side=tk.LEFT)

toggle_btn2.place(x=232, y=20)

toggle_btns.append(toggle_btn2)


title_lb2 = tk.Label(head_frame, text="Progres-2", bg="#158aff", fg="white", font=("bold", 7))

title_lb2.pack(side=tk.LEFT)

title_lb2.place(x=334, y=5)


indicator_label2 = tk.Label(head_frame, text="Naik", bg="#158aff", fg="yellow", font=("bold", 8))

indicator_label2.pack(side=tk.LEFT)

indicator_label2.place(x=368, y=55)

indicator_labels.append(indicator_label2)


# Toggle Button 3

toggle_btn3 = tk.Button(head_frame, text="☰ _ P 3", bg="#158aff", font=("bold", 6), fg="white", bd=0, activebackground="#158aff", activeforeground="white", command=lambda: toggle_menu(3, current_mode))

toggle_btn3.pack(side=tk.LEFT)

toggle_btn3.place(x=460, y=20)

toggle_btns.append(toggle_btn3)


title_lb3 = tk.Label(head_frame, text="Progres-3", bg="#158aff", fg="white", font=("bold", 7))

title_lb3.pack(side=tk.LEFT)

title_lb3.place(x=565, y=5)


indicator_label3 = tk.Label(head_frame, text="Naik", bg="#158aff", fg="yellow", font=("bold", 8))

indicator_label3.pack(side=tk.LEFT)

indicator_label3.place(x=599, y=55)

indicator_labels.append(indicator_label3)


head_frame.pack(side=tk.TOP, fill=tk.X)

head_frame.pack_propagate(False)

head_frame.configure(height=120)


options_frame.pack(side=tk.LEFT)

options_frame.pack_propagate(False)

options_frame.configure(width=170, height=300) 


# Bottom Frame

bottom_frame = tk.Frame(root, bg="#e2e2e2")

bottom_frame.pack(side=tk.TOP, fill=tk.X)


# Function to clear content frame

def clear_content_frame():

    for widget in content_frame.winfo_children():

        widget.destroy()

                  

def open_data_gn_cyan_bawah_file():

    filepath = "DATA_Gn_Cyan_Bawah(gabung).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}")      

                  

#Gugusan Nada Terpilih: "Gn_Cyan_Atas" Terpilih 

gugusan_label = tk.Label(bottom_frame, text="Gn_Cyan_Bawah", fg="tomato")

gugusan_label.grid(row=0, column=0, padx=10, pady=5, sticky="ew")  


# Data Buttons

crud_btn = tk.Button(bottom_frame, text="DATA", command=open_data_gn_cyan_bawah_file, bg="green", fg="white")

crud_btn.grid(row=5, column=0, padx=10, pady=5)


label_info = tk.Label(bottom_frame, fg="tomato", text="Pilih gugusan nada Gn_Cyan_Bawah \n untuk dirangkai dalam notasi angka lagu:\n")

label_info.grid(row=6, column=1, sticky="w", padx=0, pady=5)   


# Frame for user inputs

frame_top = tk.Frame(root)

frame_top.pack()


label_level_gn_selected = tk.Label(frame_top, text="Level Gn:")

label_level_gn_selected.grid(row=0, column=0, padx=10, pady=10)

entry_level_gn = tk.Entry(frame_top)

entry_level_gn.grid(row=0, column=1, padx=10, pady=10)


label_id_selected = tk.Label(frame_top, text="ID:")

label_id_selected.grid(row=1, column=0, padx=10, pady=10)

entry_id = tk.Entry(frame_top)

entry_id.grid(row=1, column=1, padx=10, pady=10)


label_progres = tk.Label(frame_top, text="Progres:")

label_progres.grid(row=2, column=0, padx=10, pady=10)

progres_var = tk.StringVar()

progres_combobox = ttk.Combobox(frame_top, textvariable=progres_var)

progres_combobox['values'] = (1, 2, 3)

progres_combobox.grid(row=2, column=1, padx=10, pady=10)


label_mode = tk.Label(frame_top, text="Mode:")

label_mode.grid(row=3, column=0, padx=10, pady=10)

mode_var = tk.StringVar()

mode_combobox = ttk.Combobox(frame_top, textvariable=mode_var, values=["naik", "turun"])

mode_combobox.grid(row=3, column=1, padx=10, pady=10)


label_nada = tk.Label(frame_top, text="Nada:")

label_nada.grid(row=4, column=0, padx=5, pady=5)

nada_var = tk.StringVar()

nada_combobox = ttk.Combobox(frame_top, textvariable=nada_var)

nada_combobox['values'] = ("Bass", "Trebel")

nada_combobox.grid(row=4, column=1, padx=5, pady=5)


# Hapus label, entry field, dan combobox untuk Progres dan Mode yang tidak digunakan lagi

# abel_progres.grid_forget()

# progres_combobox.grid_forget()

# label_mode.grid_forget()

# mode_combobox.grid_forget() 


separator = ttk.Separator(frame_top, orient='horizontal')

separator.grid(row=6, column=0, sticky="ew", pady=15)


# Hapus label, entry field, dan combobox untuk Progres dan Mode yang tidak digunakan lagi

# abel_progres.grid_forget()

# progres_combobox.grid_forget()

# label_mode.grid_forget()

# mode_combobox.grid_forget() 


# Fungsi membersihkan entry

def clear_entries():

    entry_level_gn.delete(0, 'end')

    entry_id.delete(0, 'end')

    progres_var.set('')

    mode_var.set('')

    nada_var.set('')

   

# Fungsi untuk mengambil data Gn_Cyan_Bawah dari database berdasarkan ID

def get_data_gn_cyan_bawah_from_db(id_selected):

    conn = sqlite3.connect("DATAMUSIK.db")

    cursor = conn.cursor()

    cursor.execute("SELECT * FROM Gn_Cyan_Bawah WHERE ID = ?", (id_selected,))

    data = cursor.fetchone()

    conn.close()

    return data

        

# Fungsi untuk mengambil data Sub_Gn_Cyan_Bawah dari database berdasarkan Sub_ID

def get_data_sub_gn_cyan_bawah_from_db(sub_id_selected):

    conn = sqlite3.connect("DATAMUSIK.db")

    cursor = conn.cursor()

    cursor.execute("SELECT * FROM Sub_Gn_Cyan_Bawah WHERE Sub_ID = ?", (sub_id_selected,))

    data = cursor.fetchone()

    conn.close()

    return data


# Fungsi untuk menyesuaikan nilai Trebel_Aneh berdasarkan progres

def adjust_trebel_aneh_value(trebel_aneh_value, progres):

    if trebel_aneh_value.isdigit():

        adjusted_value = ''.join(str(int(char) - progres) if char.isdigit() else char for char in trebel_aneh_value)

    else:

        adjusted_value = trebel_aneh_value

    return adjusted_value

    

 # Fungsi untuk menyesuaikan nilai Trebel_Aneh berdasarkan progres

def adjust_sub_trebel_aneh_value(sub_trebel_aneh_value, progres):

    if sub_trebel_aneh_value.isdigit():

        adjusted_value = ''.join(str(int(char) - progres) if char.isdigit() else char for char in sub_trebel_aneh_value)

    else:

        adjusted_value = sub_trebel_aneh_value

    return adjusted_value   

    

# Fungsi untuk menyesuaikan nilai trebel_biasa berdasarkan progres

def adjust_trebel_biasa_value(trebel_biasa_value, progres):

    if trebel_biasa_value.isdigit():

        adjusted_value = ''.join(str(int(char) - progres) if char.isdigit() else char for char in trebel_biasa_value)

    else:

        adjusted_value = trebel_biasa_value

    return adjusted_value

    

# Fungsi untuk menyesuaikan nilai Bass berdasarkan progres

def adjust_bass_value(bass_value, progres):

    if bass_value.isdigit():

        adjusted_value = ''.join(str(int(char)) if char.isdigit() else char for char in bass_value)

    else:

        adjusted_value = bass_value

    return adjusted_value       

    

# Fungsi untuk menghapus separuh karakter dari belakang

def remove_half_characters(value):

    length = len(value)

    half_length = length // 2

    return value[:half_length]    


# Fungsi untuk memilih nada Bass, Trebel Biasa, dan Trebel_Aneh 

def pilih_nada():

    try:

        level_gn_selected = int(entry_level_gn.get())

        id_selected = int(entry_id.get())

        progres_selected = int(progres_var.get())

        mode_selected = mode_var.get().lower()

        nada_selected = nada_var.get().lower()

        

        # Ambil data dari Gn_Cyan_Bawah dan Sub_Gn_Cyan_Bawah

        data_gn_cyan_bawah = get_data_gn_cyan_bawah_from_db(id_selected)

        data_sub_gn_cyan_bawah = get_data_sub_gn_cyan_bawah_from_db(1) # Sub_ID untuk Sub_Gn_Cyan_Bawah selalu 1        

        

        if not data_gn_cyan_bawah or not data_sub_gn_cyan_bawah:

            messagebox.showerror("Error", "Data tidak ditemukan. \nInput ID harus 1, 2, 3, atau 4")

            return       

  

# Fungsi untuk memilih nada Bass berdasarkan ID, progres, mode, level_gn, dan Nada 

        if level_gn_selected not in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] and nada_selected == "bass":

            messagebox.showerror("Error", "Masukkan input yang benar. \nInput level_gn harus 1, 2, 3, 4, \n5, 6, 7, 8, 9, 10, 11, atau 12 untuk Bass")

                                         

        entry_bass.delete(0, tk.END)   

        entry_sub_bass.delete(0, tk.END)                                     

        # Tampilkan nilai Bass yang telah disesuaikan berdasarkan progres

        if level_gn_selected in range(1, 13) and nada_selected == "bass":

            if progres_selected == 1:

               # Tampilkan nilai bass dari Gn_Cyan_Bawah

                entry_bass.insert(0, data_gn_cyan_bawah[2]) # bass ID 1        

                entry_sub_bass.insert(0, data_sub_gn_cyan_bawah[2]) # bass Sub_ID 1 

            else:

                # Tampilkan nilai yang telah disesuaikan berdasarkan progres

                adjusted_bass = adjust_bass_value(data_gn_cyan_bawah[2], progres_selected - 0)

                entry_bass.insert(0, adjusted_bass)

                entry_sub_bass.insert(0, adjust_bass_value(data_sub_gn_cyan_bawah[2], progres_selected - 0))                                                                                                  

            messagebox.showinfo("Success", "Data berhasil diambil dan disesuaikan")                                                                             

        clear_entries()

        

# Fungsi untuk memilih nada Trebel Aneh berdasarkan ID, progres, mode, level_gn, dan nada

        # Cek apakah level_gn_selected adalah 4, 8, atau 12

        if level_gn_selected not in [4, 8, 12] and nada_selected == "trebel":

                    

            entry_trebel_aneh.delete(0, tk.END)

            entry_sub_trebel_aneh.delete(0, tk.END)


        # Jika level_gn adalah 4, 8, atau 12, tampilkan nilai Trebel_Aneh

        if level_gn_selected in [4, 8, 12] and nada_selected == "trebel":

            if progres_selected == 1:

               # Tampilkan nilai Trebel_Aneh dari Gn_Cyan_Bawah

                entry_trebel_aneh.insert(0, data_gn_cyan_bawah[4]) # Trebel_Aneh ID 1

                entry_sub_trebel_aneh.insert(0, data_sub_gn_cyan_bawah[4]) # Trebel_Aneh Sub_ID 1


            else:

                # Tampilkan nilai yang telah disesuaikan berdasarkan progres

                adjusted_trebel_aneh = adjust_trebel_aneh_value(data_gn_cyan_bawah[4], progres_selected - 1)

                entry_trebel_aneh.insert(0, adjusted_trebel_aneh)

                entry_sub_trebel_aneh.insert(0, adjust_trebel_aneh_value(data_sub_gn_cyan_bawah[4], progres_selected - 1))

        else:

            # Jika level_gn bukan 4, 8, atau 12, kosongkan entry

            entry_trebel_aneh.delete(0, tk.END)

            entry_sub_trebel_aneh.delete(0, tk.END)


        messagebox.showinfo("Success", "Lanjut...")

        

        clear_entries()                        

                     

# Fungsi untuk memilih nada Trebel_Biasa berdasarkan ID, progres, mode, level_gn, dan nada

        # Cek apakah level_gn_selected adalah 1, 2, 3, 5, 6, 7, 9, 10, atau 11

        if level_gn_selected not in [1, 2, 3, 5, 6, 7, 9, 10, 11] and nada_selected == "trebel":

            messagebox.showerror("Error", "Lanjut...")

            return       

             

        entry_trebel_biasa.delete(0, tk.END)           

        # Cek apakah ID yang dimasukkan adalah 4, yang tidak valid

        if id_selected == 4 and nada_selected == "trebel":

            messagebox.showerror("Error", "Masukkan input yang benar. \nInput ID harus 1, 2, atau 3")

            return

            

        # Jika level_gn adalah 1, 2, 3, 5, 6, 7, 9, 10, , atau 11, tampilkan nilai trebel_biasa

        if level_gn_selected in [1, 2, 3, 5, 6, 7, 9, 10, 11] and nada_selected == "trebel":

            if progres_selected == 1:

               # Tampilkan nilai trebel_biasa dari Gn_Cyan_Bawah

                entry_trebel_biasa.insert(0, data_gn_cyan_bawah[3]) # trebel_biasa ID 1                

            else:

                # Tampilkan nilai yang telah disesuaikan berdasarkan pogres

                adjusted_trebel_biasa = adjust_trebel_biasa_value(data_gn_cyan_bawah[3], progres_selected - 1)

                entry_trebel_biasa.insert(0, adjusted_trebel_biasa)

                

        else:

            # Jika level_gn bukan 1, 2, 3, 5, 6, 7, 9, 10, atau 11, kosongkan entry

            entry_trebel_biasa.delete(0, tk.END)

            

            messagebox.showerror("Error", "Lanjut...terus")   

    except ValueError:

        messagebox.showerror("Error", "ID, Level_Gn, dan Progres harus berupa angka")                     

                                                          

    finally:    

        clear_entries()

                             

# Fungsi untuk memastikan urutan Level_Gn dan ID

def level_gn():

    try:  

        level_gn_selected = int(entry_level_gn.get())       

        if level_gn_selected in [1, 5, 9]:

            id_selected = 1

        elif level_gn_selected in [2, 6, 10]:

            id_selected = 2

        elif level_gn_selected in [3, 7, 11]:

            id_selected = 3

        elif level_gn_selected in [4, 8, 12]:

            id_selected = 4

        else:

            messagebox.showerror("Error", "Level_Gn ada 1-12. L-1 = L-5 = L-9 = ID 1, L-2 = L-6 = L-10 = ID 2, L-3 = L-7 = L-11 = ID 3, L-4 = L-8 = L-12 = ID 4")

            return None

        

        entry_id.delete(0, 'end')

        entry_id.insert(0, str(id_selected))


        id_selected_sub = 1


        return id_selected, id_selected_sub


    except ValueError:

        messagebox.showerror("Error", "Masukkan nilai Level_Gn yang valid!")

        return None, None  

        

# Bottom Frame

bottom_frame = tk.Frame(root, bg="#e2e2e2")

bottom_frame.pack(side=tk.TOP, fill=tk.X)


# Label Gugusan Nada Terpilih Field

Gn_tetpilih_label = tk.Label(bottom_frame, text="Gugusan- \n Nada Terpilih:")

Gn_tetpilih_label.grid(row=8, column=0, padx=5, pady=5)


#Label dan Entry Ambil Gugusan nada Teroilih

label_bass = tk.Label(bottom_frame, text="Bass Gn Cyan Bawah:")

label_bass.grid(row=7, column=1, padx=5, pady=5)

entry_bass = tk.Entry(bottom_frame)

entry_bass.grid(row=8, column=1, padx=5, pady=5)


label_sub_bass = tk.Label(bottom_frame, text="Sub Bass Gn Cyan Bawah:")

label_sub_bass.grid(row=7, column=2, padx=5, pady=5)

entry_sub_bass = tk.Entry(bottom_frame)

entry_sub_bass.grid(row=8, column=2, padx=5, pady=5)


label_trebel_biasa = tk.Label(bottom_frame, text="Trebel Biasa \n Gn Cyan Bawah")

label_trebel_biasa.grid(row=7, column=3, padx=5, pady=5)

entry_trebel_biasa = tk.Entry(bottom_frame)

entry_trebel_biasa.grid(row=8, column=3, padx=5, pady=5)


entry_sub_trebel_biasa = tk.Entry(bottom_frame)

entry_sub_trebel_biasa.grid(row=8, column=4, padx=5, pady=5)


label_trebel_aneh = tk.Label(bottom_frame, text="Trebel Aneh \n Gn Cyan Bawah")

label_trebel_aneh.grid(row=10, column=3, padx=5, pady=5)

entry_trebel_aneh = tk.Entry(bottom_frame)

entry_trebel_aneh.grid(row=11, column=3, padx=5, pady=5)


label_sub_tre


Berikut ini adalah cara menambahkan fungsi pengguliran (scrolling) ke segala arah pada kode yang telah Anda berikan. Saya akan membuat perubahan yang diperlukan untuk memastikan bahwa semua elemen GUI berada di dalam sebuah `scrollbar_frame`, yang memungkinkan pengguliran baik secara vertikal maupun horizontal.


Berikut adalah versi modifikasi dari kode Anda dengan fungsi pengguliran:


```python

import tkinter as tk

from tkinter import ttk

import sqlite3

from tkinter import messagebox

from tkinter import filedialog

from tkinter import Tk, Label, Entry, Button, Frame, StringVar

import subprocess

import os

import logging


# Initialize logging

logging.basicConfig(level=logging.INFO)


# Initialize the main window

root = tk.Tk()

root.geometry("690x1390")

root.title("Arah Arus Musik")    


# Create a canvas for scrollbar and a frame for all content

scrollbar_frame = tk.Frame(root)

scrollbar_frame.pack(fill=tk.BOTH, expand=True)


canvas = tk.Canvas(scrollbar_frame)

canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)


scrollbar_y = tk.Scrollbar(scrollbar_frame, orient=tk.VERTICAL, command=canvas.yview)

scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)


scrollbar_x = tk.Scrollbar(scrollbar_frame, orient=tk.HORIZONTAL, command=canvas.xview)

scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)


canvas.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)


# Create an inner frame inside the canvas

inner_frame = tk.Frame(canvas)

canvas.create_window((0, 0), window=inner_frame, anchor="nw")


# Update the scroll region when the inner frame changes size

def on_frame_configure(event):

    canvas.configure(scrollregion=canvas.bbox("all"))


inner_frame.bind("<Configure>", on_frame_configure)


# Head Frame

head_frame = tk.Frame(inner_frame, bg="#158aff", highlightbackground="white", highlightthickness=1)

head_frame.place()


# Content Frame

content_frame = tk.Frame(inner_frame)

content_frame.pack()


# Koneksi ke database dan inisialisasi tabel jika belum ada

def init_db():

    conn = sqlite3.connect('DATAMUSIK.db')

    c = conn.cursor()

    c.execute('''

        CREATE TABLE IF NOT EXISTS Gn_Cyan_Bawah (

            ID INTEGER PRIMARY KEY,

            Level_R TEXT,

            Bass INT,            

            Trebel_Biasa INT,

            Trebel_Aneh INT

        )

    ''')

    c.execute('''

        CREATE TABLE IF NOT EXISTS Sub_Gn_Cyan_Bawah(

            Sub_ID INTEGER PRIMARY KEY,

            Level_D TEXT,

            Bass INT,

            Trebel_Biasa INT,

            Trebel_Aneh INT    

        )

    ''')

    conn.commit()

    conn.close()


# Function to clear content frame

def clear_content_frame():

    for widget in content_frame.winfo_children():

        widget.destroy()                                                                                

# Function to switch modes and update pages

def switch_mode(progres, mode):

    if mode[progres - 1] == "naik":

        mode[progres - 1] = "turun"

        setup_turun_mode(progres)

    else:

        mode[progres - 1] = "naik"

        setup_naik_mode(progres)

        

# Options Frame

options_frame = tk.Frame(inner_frame, bg="#c3c3c3") 


# Current mode for each toggle button

current_mode = ['naik', 'naik', 'naik']

toggle_btns = []

indicator_labels = []

pages = [

    ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass'],

    ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass'],

    ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

]                                                

                                     

# Function to toggle menus

def toggle_menu(progres, mode):

    if mode[progres - 1] == 'naik':

        mode[progres - 1] = 'turun'

        toggle_btns[progres - 1].config(text="X _ T")

        pages[progres - 1] = ['Gn_A_Bass', 'Gn_Biru', 'Gn_Cyan_Bawah', 'Gn_A_Trebel']

        indicator_labels[progres - 1].config(text="Turun")

    else:

        mode[progres - 1] = 'naik'

        toggle_btns[progres - 1].config(text="☰ _ N")

        pages[progres - 1] = ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

        indicator_labels[progres - 1].config(text="Naik")

    

    update_options_frame(progres)

    display_pages(progres)

    

# Function to display pages

def display_pages(progres):

    for widget in content_frame.winfo_children():

        widget.destroy()


    display_gn_cyan_bawah_page()


# Function to display default page

def display_gn_cyan_bawah_page():

    clear_content_frame()

    tk.Label(content_frame, text="Ini adalah Halaman Gn_Cyan_Bawah", font=("Helvetica", 10)).pack()    

              

# Function to setup "Naik" mode

def setup_naik_mode(progres):

    if progres == 1:

        pages[0] = ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

    elif progres == 2:

        pages[1] = ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

    elif progres == 3:

        pages[2] = ['Gn_A_Trebel', 'Gn_Biru', 'Gn_Cyan_Atas', 'Gn_A_Bass']

    

# Function to setup "Turun" mode

def setup_turun_mode(progres):

    if progres == 1:

        pages[0] = ['Gn_A_Bass', 'Gn_Biru', 'Gn_Cyan_Bawah', 'Gn_A_Trebel']

    elif progres == 2:

        pages[1] = ['Gn_A_Bass', 'Gn_Biru', 'Gn_Cyan_Bawah', 'Gn_A_Trebel']

    elif progres == 3:

        pages[2] = ['Gn_A_Bass', 'Gn_Biru', 'Gn_Cyan_Bawah', 'Gn_A_Trebel']

                 

# Toggle Button 1

toggle_btn1 = tk.Button(head_frame, text="☰ _ P 1", bg="#158aff", font=("bold", 6), fg="white", bd=0, activebackground="#158aff", activeforeground="white", command=lambda: toggle_menu(1, current_mode))

toggle_btn1.pack(side=tk.LEFT)

toggle_btn1.place(x=5, y=20)

toggle_btns.append(toggle_btn1)


title_lb1 = tk.Label(head_frame, text="Progres-1", bg="#158aff", fg="white", font=("bold", 7))

title_lb1.pack(side=tk.LEFT)

title_lb1.place(x=108, y=11)


indicator_label1 = tk.Label(head_frame, text="Naik", bg="#158aff", fg="yellow", font=("bold", 8))

indicator_label1.pack(side=tk.LEFT)

indicator_label1.place(x=127, y=55)

indicator_labels.append(indicator_label1)


# Toggle Button 2

toggle_btn2 = tk.Button(head_frame, text="☰ _ P 2", bg="#158aff", font=("bold", 6), fg="white", bd=0, activebackground="#158aff", activeforeground="white", command=lambda: toggle_menu(2, current_mode))

toggle_btn2.pack(side=tk.LEFT)

toggle_btn2.place(x=232, y=20)

toggle_btns.append(toggle_btn2)


title_lb2 = tk.Label(head_frame, text="Progres-2", bg="#158aff", fg="white", font=("bold", 7))

title_lb2.pack(side=tk.LEFT)

title_lb2.place(x=334, y=5)


indicator_label2 = tk.Label(head_frame, text="Naik", bg="#158aff", fg="yellow", font=("bold", 8))

indicator_label2.pack(side=tk.LEFT)

indicator_label2.place(x=368, y=55)

indicator_labels.append(indicator_label2)


# Toggle Button 3

toggle_btn3 = tk.Button(head_frame, text="☰ _ P 3", bg="#158aff", font=("bold", 6), fg="white", bd=0, activebackground="#158aff", activeforeground="white", command=lambda: toggle_menu(3, current_mode))

toggle_btn3.pack(side=tk.LEFT)

toggle_btn3.place(x=460, y=20)

toggle_btns.append(toggle_btn3)


title_lb3 = tk.Label(head_frame, text="Progres-3", bg="#158aff", fg="white", font=("bold", 7))

title_lb3.pack(side=tk.LEFT)

title_lb3.place(x=565, y=5)


indicator_label3 = tk.Label(head_frame, text="Naik", bg="#158aff", fg="yellow", font=("bold", 8))

indicator_label3.pack(side=tk.LEFT)

indicator_label3.place(x=599, y=55)

indicator_labels.append(indicator_label3)


head_frame.pack(side=tk.TOP, fill=tk.X)

head_frame.pack_propagate(False)

head_frame.configure(height=120


Kode di atas menunjukkan implementasi untuk menjalankan berbagai file Python yang mengelola bagian-bagian berbeda dari program musik yang sedang Anda kembangkan, serta menyediakan UI untuk memilih halaman atau file yang akan dieksekusi. Berikut adalah beberapa penyesuaian dan tambahan yang mungkin Anda perlukan untuk melengkapi dan memperbaiki kode tersebut:


1. **Konsistensi Nama Fungsi dan Variabel:**

   - Pada bagian kode ini:

     ```python

     select_button = tk.Button(bottom_frame, text="Pilih Nada", bg="green", fg="white", command=pilih_nada)

     ```

     Pastikan bahwa fungsi `pilih_nada()` telah didefinisikan sebelumnya. Jika tidak, pastikan Anda menggantinya dengan fungsi yang sesuai atau mendefinisikan fungsi tersebut.


2. **Penanganan Halaman Aktif:**

   - Anda telah mendeklarasikan variabel `active_page`, tetapi belum digunakan di dalam fungsi. Jika Anda berencana untuk melacak halaman yang aktif dan mungkin ingin mengubah perilaku berdasarkan halaman yang saat ini aktif, Anda perlu menambahkannya dalam logika `update_options_frame` atau pada bagian lain yang relevan.

   - Contoh:

     ```python

     def run_gn_cyan_bawah_file():

         global active_page

         active_page = "Gn_Cyan_Bawah"

         filepath = "CRUD_Gn_Cyan_Bawah(gabung).py"

         ...

     ```


3. **Pengaturan Fungsi Naik dan Turun:**

   - Untuk implementasi `next_to_crud_gn_cyan_atas()` dan `next_to_crud_gn_a_trebel()`, Anda harus menambahkan logika yang sesuai untuk mengubah halaman dan memastikan pengelolaan file dilakukan dengan benar. Berikut adalah contoh fungsi tersebut:

     ```python

     def next_to_crud_gn_cyan_atas():

         clear_content_frame()

         run_gn_cyan_atas_file()

         tk.Label(content_frame, text="Ini adalah halaman Gn_Cyan_Atas", font=("Helvetica", 10)).pack()


     def next_to_crud_gn_a_trebel():

         clear_content_frame()

         run_gn_a_trebel_file()

         tk.Label(content_frame, text="Ini adalah halaman Gn_A_Trebel", font=("Helvetica", 10)).pack()

     ```


4. **Inisialisasi Halaman Default:**

   - Pada `init_default_page()`, Anda perlu memastikan bahwa halaman default diinisialisasi dengan benar:

     ```python

     def init_default_page():

         update_options_frame(1) # Default untuk Progres-1

         clear_content_frame()

         tk.Label(content_frame, text="Halaman Default Gugus Nada", font=("Helvetica", 10)).pack()

         Gn_Cyan_Bawah_page() # Misalnya, set default ke Gn_Cyan_Bawah

     ```


5. **Penanganan Error dan Debugging:**

   - Menjalankan file dengan `exec()` memiliki risiko, terutama jika terdapat bug dalam file tersebut. Pastikan Anda telah mengelola error dengan baik dan memberikan pesan yang cukup informatif kepada pengguna jika terjadi kesalahan.


6. **Tombol dan Indikator:**

   - Anda sudah memiliki kode yang cukup baik untuk menampilkan tombol dan indikator pada `options_frame`. Pastikan Anda telah menyesuaikan tata letak sesuai dengan desain UI yang diinginkan.


Dengan melengkapi kode di atas, Anda dapat membangun antarmuka yang memungkinkan pengguna berpindah antara halaman-halaman yang berbeda dari program musik Anda dan mengeksekusi file Python yang relevan. Jika Anda memiliki pertanyaan atau perlu bantuan lebih lanjut dengan logika atau struktur program, jangan ragu untuk bertanya!


Berikut sambungan dari kodenya:

# Fungsi untuk membuka file CRUD_Gn_Cyan_Bawah(gabung).py 

active_page = None # Menyimpan halaman aktif

# Fungsi untuk menjalankan file CRUD_Gn_A_Trebel.py, CRUD_Gn_Biru.py, CRUD_Gn_Cyan_Bawah.py, CRUD_Gn_Cysn_Atas.py, dan CRUD_Gn_A_Bass.py

def run_gn_a_trebel_file():

    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 run_gn_biru_file():

    filepath = "CRUD_Gn_Biru.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 run_gn_cyan_bawah_file():

    filepath = "CRUD_Gn_Cyan_Bawah(gabung).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 run_gn_cyan_atas_file():

    filepath = "CRUD_Gn_Cyan_Atas(gabung).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 run_gn_a_bass_file():

    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}")                

               

# Function to display the options based on the current mode and progress

def update_options_frame(progres):

    # Clear existing buttons

    for widget in options_frame.winfo_children():

        widget.destroy()


    if current_mode[progres - 1] == "turun":

        Gn_Cyan_Bawah_btn = tk.Button(options_frame, text="Gn_Cyan_Bawah", font=("bold", 5), fg="yellow", bd=0, bg="green", command=run_gn_cyan_bawah_file)

        Gn_Cyan_Bawah_btn.place(x=3, y=0)

        

        Gn_Cyan_Bawah_indicate = tk.Label(options_frame, text="Ini Gn_Cyan_Bawah ", bg="#c3c3c3")

        Gn_Cyan_Bawah_indicate.place(x=2, y=155, width=5, height=45)    

        

        Gn_A_Trebel_btn = tk.Button(options_frame, text="Gn_A_Trebel", font=("bold", 6), fg="yellow", bd=0, bg="grey", command=run_gn_a_trebel_file)

        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)    


    else: # Mode "naik"

        Gn_Cyan_Bawah_btn = tk.Button(options_frame, text="Gn_Cyan_Bawah", font=("bold", 5), fg="yellow", bd=0, bg="green", command=run_gn_cyan_bawah_file)

        Gn_Cyan_Bawah_btn.place(x=3, y=0)

        

        Gn_Cyan_Bawah_indicate = tk.Label(options_frame, text="Ini Gn_Cyan_Bawah ", bg="#c3c3c3")

        Gn_Cyan_Bawah_indicate.place(x=2, y=5, width=5, height=45)    


        Gn_Cyan_Atas_btn = tk.Button(options_frame, text="Gn_Cyan_Atas", font=("bold", 5), fg="yellow", bd=0, bg="green", command=run_gn_cyan_atas_file)

        Gn_Cyan_Atas_btn.place(x=3, y=50)

        

        Gn_Cyan_Atas_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")

        Gn_Cyan_Atas_indicate.place(x=2, y=55, width=5, height=45)    


        Gn_Biru_btn = tk.Button(options_frame, text="Gn_Biru", font=("bold", 7), fg="yellow", bd=0,bg="blue", command=run_gn_biru_file)

        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_A_Bass_btn = tk.Button(options_frame, text="Gn_A_Bass", font=("bold", 7), fg="yellow", bd=0, bg="grey", command=run_gn_a_bass_file)

        Gn_A_Bass_btn.place(x=3, y=150)

        

        Gn_A_Bass_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")

        Gn_A_Bass_indicate.place(x=2, y=155, width=5, height=45)

        

# Call update_options_frame for the initial setup

update_options_frame(1)


# Function to display Gn_A_Trebel page

def Gn_A_Trebel_page():

    clear_content_frame()

    tk.Label(content_frame, text="Ini adalah halaman Gn_A_Trebel", font=("Helvetica", 10)).pack()      


# Function to display Gn_Biru page

def Gn_Biru_page():

    clear_content_frame()

    tk.Label(content_frame, text="Ini adalah halaman Gn_Biru", font=("Helvetica", 10)).pack()


# Function to display Gn_Cyan_Bawah page

def Gn_Cyan_Bawah_page():

    clear_content_frame()

    tk.Label(content_frame, text="Ini adalah halaman Gn_Cyan_Bawah", font=("Helvetica", 10)).pack()

    

# Function to display Gn_Cyan_Atas page

def Gn_Cyan_Atas_page():

    clear_content_frame()

    tk.Label(content_frame, text="Ini adalah halaman Gn_Cyan_Atas", font=("Helvetica", 10)).pack()    


# Function to display Gn_Biru page

def Gn_A_Bass_page():

    clear_content_frame()

    tk.Label(content_frame, text="Ini adalah halaman Gn_A_Bass", font=("Helvetica", 10)).pack()


# Initialize the default page

def init_default_page():

    update_options_frame(1) # Default to showing options for Progres-1

    clear_content_frame()

    tk.Label(content_frame, text="Halaman Default Gugus Nada", font=("Helvetica", 10)).pack()

    

    #Fungsi tombol di options_frame        

    Gn_A_Trebel_btn = tk.Button(options_frame, text="Gn_A_Trebel", font=("bold", 6), fg="yellow", bd=0, bg="grey", command=run_gn_a_trebel_file)

    Gn_A_Trebel_btn.place(x=3, y=0)

    

    Gn_A_Trebel_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")

    Gn_A_Trebel_indicate.place(x=2, y=5, width=5, height=45)  

        

    Gn_Biru_btn = tk.Button(options_frame, text="Gn_Biru", font=("bold", 7), fg="yellow", bd=0,bg="blue", command=run_gn_biru_file)

    Gn_Biru_btn.place(x=3, y=50)

        

    Gn_Biru_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")

    Gn_Biru_indicate.place(x=2, y=55, width=5, height=45)     

    

    Gn_Cyan_Bawah_btn = tk.Button(options_frame, text="Gn_Cyan_Bawah", font=("bold", 5), fg="yellow", bd=0, bg="green", command=run_gn_cyan_bawah_file)

    Gn_Cyan_Bawah_btn.place(x=3, y=100)                  

    Gn_Cyan_Bawah_indicate = tk.Label(options_frame, text="Ini Gn_Cyan_Bawah ", bg="#c3c3c3")

    Gn_Cyan_Bawah_indicate.place(x=2, y=105, width=5, height=45)    


    Gn_Cyan_Atas_btn = tk.Button(options_frame, text="Gn_Cyan_Atas", font=("bold", 5), fg="yellow", bd=0, bg="green", command=run_gn_cyan_atas_file)

    Gn_Cyan_Atas_btn.place(x=3, y=150)

        

    Gn_Cyan_Atas_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")

    Gn_Cyan_Atas_indicate.place(x=2, y=155, width=5, height=45)    


    Gn_A_Bass_btn = tk.Button(options_frame, text="Gn_A_Bass", font=("bold", 7), fg="yellow", bd=0, bg="grey", command=run_gn_a_bass_file)

    Gn_A_Bass_btn.place(x=3, y=200)

        

    Gn_A_Bass_indicate = tk.Label(options_frame, text=" ", bg="#c3c3c3")

    Gn_A_Bass_indicate.place(x=2, y=205, width=5, height=45)

    

# Tombol untuk memilih nada

select_button = tk.Button(bottom_frame, text="Pilih Nada", bg="green", fg="white", command=pilih_nada)

select_button.grid(row=5, column=1, padx=5, pady=5)


separator = ttk.Separator(bottom_frame, orient='horizontal')

separator.grid(row=6, column=0, sticky="ew", pady=15)


# Fungsi untuk Naik ke Gn_Cyan_Atas (file CRUD_Gn_Cyan_Atas(gabung).py, atau Turum ke Gn_A_Trebel (file CRUD_Gn_A_Trebel.py)

active_page = None # Menyimpan halaman aktif

def next_to_crud_gn_cyan_atas():

    filepath = "CRUD_Gn_Cyan_Atas(gabung).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 next_to_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 Tombol Ambil Gugusan nada Teroilih

copy_bass_gn_cyan_bawah_btn = tk.Button(bottom_frame, text="Copy Bass", command=None, bg="lightgreen", fg="blue")

copy_bass_gn_cyan_bawah_btn.grid(row=9, column=1, padx=10, pady=5)

copy_bass_sub_gn_cyan_bawah_btn = tk.Button(bottom_frame, text="Copy Sub_Bass", command=None, bg="lightgreen", fg="blue")

copy_bass_sub_gn_cyan_bawah_btn.grid(row=9, column=2, padx=10, pady=5)


copy_trebel_gn_cyan_bawah_btn = tk.Button(bottom_frame, text="Copy Trebel_Biasa", command=None, bg="lightgreen", fg="blue")

copy_trebel_gn_cyan_bawah_btn.grid(row=9, column=3, padx=10, pady=5)


copy_trebel_aneh_gn_cyan_bawah_btn = tk.Button(bottom_frame, text="Copy Trebel_Aneh", command=None, bg="lightgreen", fg="blue")

copy_trebel_aneh_gn_cyan_bawah_btn.grid(row=12, column=3, padx=10, pady=5)

copy_trebel_aneh_sub_gn_cyan_bawah_btn = tk.Button(bottom_frame, text="Copy Sub_Trebel_Aneh", command=None, bg="lightgreen", fg="blue")

copy_trebel_aneh_sub_gn_cyan_bawah_btn.grid(row=12, column=4, padx=10, pady=5)


separator = ttk.Separator(bottom_frame, orient='horizontal')

separator.grid(row=10, column=0, sticky="ew", pady=15)


prev_btn = tk.Button(bottom_frame, text="< Prev", command=None, bg="orange", fg="white")

prev_btn.grid(row=13, column=0, padx=10, pady=5)


naik_btn = tk.Button(bottom_frame, text=" Naik Lagi > ", command=next_to_crud_gn_cyan_atas, bg="orange", fg="white")

naik_btn.grid(row=12, column=1, padx=10, pady=5)


turun_btn = tk.Button(bottom_frame, text="Turun Lagi >", command=next_to_crud_gn_a_trebel, bg="orange", fg="white")

turun_btn.grid(row=13, column=1, padx=10, pady=5)      

       

# Inisialisasi database 

init_db()    


# Main Function

if __name__ == "__main__":

    

    init_default_page()

    root.mainloop()                   


Berikut adalah sambungan dari kode yang telah Anda berikan, serta beberapa penjelasan untuk memastikan fungsionalitas berjalan dengan baik:


```python

        messagebox.showerror("Error", f"Failed to execute file: {e}")


def next_to_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 untuk membersihkan frame konten

def clear_content_frame():

    for widget in content_frame.winfo_children():

        widget.destroy()


# Fungsi untuk memilih Nada (dipanggil dari tombol Pilih Nada)

def pilih_nada():

    # Implementasikan logika sesuai kebutuhan di sini

    pass


# Pengaturan Frame Utama

main_frame = tk.Frame(root, bg="white")

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


# Inisialisasi Halaman Default

init_default_page()


# Menjalankan Tkinter mainloop

root.mainloop()

```


### Penjelasan Tambahan:

1. **`next_to_crud_gn_cyan_atas()` dan `next_to_crud_gn_a_trebel()`**: 

   - Fungsi ini mengatur perpindahan ke halaman yang sesuai, dengan membuka dan mengeksekusi file yang relevan. Jika ada masalah dalam mengeksekusi file, akan muncul pesan error.


2. **`clear_content_frame()`**:

   - Fungsi ini memastikan bahwa konten di `content_frame` dihapus sebelum memuat konten baru.


3. **`pilih_nada()`**:

   - Fungsi ini perlu diimplementasikan sesuai logika aplikasi Anda untuk menangani pemilihan nada.


4. **`init_default_page()`**:

   - Memastikan halaman default ditampilkan dengan pilihan nada yang sesuai saat aplikasi pertama kali dijalankan.


5. **`main_frame` dan `root.mainloop()`**:

   - `main_frame` adalah frame utama di dalam root yang menampung semua elemen lainnya, dan `mainloop()` memastikan aplikasi tetap berjalan dan merespons interaksi pengguna.


Kode ini sekarang sudah lengkap untuk memastikan aplikasi berfungsi dengan baik, memungkinkan pengguna berpindah antara halaman-halaman yang berbeda sesuai pilihan mereka. Pastikan setiap file yang dipanggil oleh `exec` tersedia dan berfungsi dengan baik.


Berikut adalah cara untuk menambahkan fungsi pengguliran ke segala arah dengan menempatkan semua elemen GUI dan fungsi ke dalam `scrollbar_frame`. Saya akan mengintegrasikan pengaturan scrollbar dan membungkus elemen-elemen GUI di dalam frame yang dapat digulir.


Tambahkan kode berikut ini ke dalam aplikasi Anda:


```python

import tkinter as tk

from tkinter import ttk


root = tk.Tk()

root.title("Scrollable GUI Example")


# Create the main frame (scrollbar frame)

scrollbar_frame = tk.Frame(root)

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


# Add a canvas widget inside the scrollbar frame

canvas = tk.Canvas(scrollbar_frame)

canvas.pack(side="left", fill="both", expand=True)


# Create vertical and horizontal scrollbars

v_scrollbar = tk.Scrollbar(scrollbar_frame, orient="vertical", command=canvas.yview)

v_scrollbar.pack(side="right", fill="y")


h_scrollbar = tk.Scrollbar(scrollbar_frame, orient="horizontal", command=canvas.xview)

h_scrollbar.pack(side="bottom", fill="x")


# Configure the canvas to use the scrollbars

canvas.configure(yscrollcommand=v_scrollbar.set, xscrollcommand=h_scrollbar.set)

canvas.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))


# Create another frame inside the canvas

content_frame = tk.Frame(canvas)

canvas.create_window((0, 0), window=content_frame, anchor="nw")


# Add all your widgets inside content_frame instead of root

# Sambungkan kode sebelumnya ke dalam content_frame ini


# Fungsi untuk membuka file CRUD_Gn_Cyan_Bawah(gabung).py 

active_page = None # Menyimpan halaman aktif


# Fungsi untuk menjalankan file CRUD_Gn_A_Trebel.py, CRUD_Gn_Biru.py, CRUD_Gn_Cyan_Bawah.py, CRUD_Gn_Cyan_Atas.py, dan CRUD_Gn_A_Bass.py

def run_gn_a_trebel_file():

    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}")    


# (Lanjutkan menambahkan fungsi run lainnya sesuai kode Anda...)


# Function to display the options based on the current mode and progress

def update_options_frame(progres):

    # Clear existing buttons

    for widget in options_frame.winfo_children():

        widget.destroy()


    # (Tambahkan isi update_options_frame Anda di sini...)


# Initialize the default page

def init_default_page():

    update_options_frame(1) # Default to showing options for Progres-1

    clear_content_frame()

    tk.Label(content_frame, text="Halaman Default Gugus Nada", font=("Helvetica", 10)).pack()


# Create your frames inside the content_frame

options_frame = tk.Frame(content_frame)

options_frame.pack(side="left", fill="y")


content_display_frame = tk.Frame(content_frame)

content_display_frame.pack(side="right", fill="both", expand=True)


# Initialize the GUI

init_default_page()


# Function to clear the content frame

def clear_content_frame():

    for widget in content_display_frame.winfo_children():

        widget.destroy()


# Example of adding widgets inside content_frame

tk.Label(content_frame, text="Example Scrollable Frame", font=("Helvetica", 12)).pack()


# Tambahkan elemen GUI lainnya di sini...


root.mainloop()

```


### Penjelasan:

1. **Frame Utama (`scrollbar_frame`)**: Dibuat untuk menampung `canvas` yang akan digunakan untuk melakukan pengguliran.

2. **`Canvas`**: Ini adalah area di mana semua elemen GUI ditempatkan dan dapat digulir ke segala arah. `canvas` ini terhubung dengan scrollbars (vertikal dan horizontal).

3. **`content_frame`**: Semua elemen GUI, termasuk frame `options_frame` dan `content_display_frame`, dimasukkan ke dalam `content_frame` ini yang diletakkan di dalam `canvas`.

4. **`Scrollbars`**: Kedua scrollbars (vertikal dan horizontal) mengendalikan pengguliran `canvas`.


Dengan menempatkan semua elemen GUI ke dalam `content_frame` yang berada di dalam `canvas`, Anda akan mendapatkan kemampuan untuk menggulir konten ke segala arah. Anda bisa menambahkan semua elemen dan fungsi GUI yang Anda miliki ke dalam `content_frame` untuk menggunakan fitur pengguliran ini.


Selesai ...



Komentar

Postingan populer dari blog ini

Pemograman R Studio

  Metode Numerik Menggunakan R Pengantar Gambaran Isi Buku Cara Berkontribusi dalam Buku Ini Ucapan Terima Kasih Lisensi 1  Bahasa Pemrograman R 1.1  Sejarah R 1.2  Fitur dan Karakteristik R 1.3  Kelebihan dan Kekurangan R 1.4  RStudio 1.5  Menginstall R dan RStudio 1.6  Working Directory 1.6.1  Mengubah Lokasi Working Directory 1.6.2  Mengubah Lokasi Working Directory Default 1.7  Memasang dan Mengaktifkan Paket R 1.8  Fasilitas Help 1.8.1  Mencari Help dari Suatu Perintah Tertentu 1.8.2  General Help 1.8.3  Fasilitas Help Lainnya 1.9  Referensi 2  Kalkulasi Menggunakan R 2.1  Operator Aritmatik 2.2  Fungsi Aritmetik 2.3  Operator Relasi 2.4  Operator Logika 2.5  Memasukkan Nilai Kedalam Variabel 2.6  Tipe dan Struktur Data 2.7  Vektor 2.7.1  Membuat vektor 2.7.2  Missing Values 2.7.3  Subset Pada Vektor 2.7.4  Operasi Matematis Menggunakan Vektor ...

MIGRASI DATABASE DARI SQLite KE MySQL (Part-1)

  MIGRASI DATABASE DARI SQLite KE MySQL (Part-1) Pemakaian yang mana lebih baik dalam membuat database_musik di mysql atau Exel yang cell Cell pada tabel dilakukan operasi fungsi logika matematika. Untuk keperluan membuat database atau tabel yang memerlukan operasi logika atau matematika, seperti yang Anda sebutkan, MySQL jauh lebih baik dibandingkan Excel. Berikut adalah beberapa alasan mengapa MySQL lebih disarankan: 1. **Kapasitas dan Skalabilitas**: MySQL dapat menangani jumlah data yang jauh lebih besar daripada Excel. Ini penting jika Anda berencana untuk menyimpan banyak data atau melakukan operasi yang kompleks di atas data tersebut. 2. **Kekuatan dan Kinerja**: MySQL dirancang khusus untuk memproses query dan operasi basis data dengan cepat. Ini termasuk operasi matematika, logika, dan agregasi data yang umum dilakukan dalam aplikasi. 3. **Fleksibilitas Struktur**: Dalam MySQL, Anda dapat dengan mudah menentukan struktur tabel yang kompleks dan melakukan kueri yang lebih r...

Cara Menjadi Pengembang Front End – Keterampilan Front End Web Dev

  Menyumbangkan Belajar coding —  kurikulum 3.000 jam gratis 10 JUNI 2022 / #PENGEMBANGAN UJUNG DEPAN Bagaimana Menjadi Pengembang Front End – Keterampilan Front End Web Dev Joel Olawanle Beberapa profesional dengan bayaran tertinggi di dunia adalah pengembang front-end.  Mereka menggunakan pengetahuan dan bakat mereka untuk merancang situs web yang menarik dan ramah pengguna. Pengembang front-end tidak memerlukan gelar atau sertifikat sekolah untuk bekerja.  Sebaliknya, mereka harus memahami dasar-dasar pengembangan front-end, bahasa pemrograman, dan kerangka kerja pengembangan front-end. Dalam panduan ini, Anda akan belajar bagaimana menjadi pengembang front end dengan terlebih dahulu memahami apa yang dimaksud dengan pengembangan front end, keterampilan teknis dan soft skill yang diperlukan, bahasa dan kerangka kerja yang tersedia, dan beberapa langkah untuk memulai. Seorang pengembang front-end di Amerika Serikat dapat memperoleh rata-rata $86,178 per tahun, menu...