MEMBUAT TEMPLATE DAN KELENGKAPAN PARTITUR NOTASI ANGKA LAGU (Part-4)
Tolong gabung kode berikut:
# Fungsi untuk menampilkan partitur dengan indentasi
def show_partitur():
output_text.delete(1.0, tk.END) # Hapus konten sebelumnya
output_text.insert(tk.END, "Berikut adalah template partitur dengan birama 4/4:\n\n")
output_text.insert(tk.END, create_birama_template() + "\n")
output_text.insert(tk.END, "Lirik: " + " " * (len(create_birama_template()) - 7) + "|\n\n")
# Kotak teks untuk output partitur
output_text = tk.Text(output_frame, wrap="none", width=80, height=40, undo=True, font=("Courier", 12))
output_text.grid(row=2, column=0, padx=10, pady=5)
# Tombol untuk menambah birama baru
button_add_birama = tk.Button(chord_frame, text="Tambah Birama", command=add_birama)
button_add_birama.grid(row=1, column=4, padx=(1, 2), pady=5)
# Tombol untuk menampilkan template partitur
button_show_partitur = tk.Button(chord_frame, text="Tampilkan Partitur", command=show_partitur)
button_show_partitur.grid(row=1, column=5, padx=(1, 2), pady=5)
# Configure tags for text styling
output_text.tag_configure("superscript", offset=8) # Superscript untuk chord
output_text.tag_configure("chord_color", foreground="blue") # Warna biru untuk chord
# Menambahkan scrollbar ke Text Widget
output_text_scrollbar_y = tk.Scrollbar(output_frame, orient=tk.VERTICAL, command=output_text.yview)
output_text_scrollbar_y.grid(row=2, column=1, sticky='ns')
output_text.configure(yscrollcommand=output_text_scrollbar_y.set)
output_text_scrollbar_x = tk.Scrollbar(output_frame, orient=tk.HORIZONTAL, command=output_text.xview)
output_text_scrollbar_x.grid(row=3, column=0, sticky='ew')
output_text.configure(xscrollcommand=output_text_scrollbar_x.set)
# Run the Tkinter main loop
root.mainloop()
Dengan kode yang ini:
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk
# Setup UI
root = tk.Tk()
root.geometry("690x1390")
root.title("Partitur Notasi Angka dengan Font Khusus")
# Skala Mayor dan Minor
skala_mayor = [2, 2, 1, 2, 2, 2, 1]
skala_minor = [2, 1, 2, 2, 1, 2, 2]
akord_tampil = False # Flag untuk mengecek apakah tombol "Tampilkan Akord" sudah ditekan
# Fungsi untuk mengubah nada berdasarkan interval
def generate_scale(nada_dasar_value, intervals):
all_notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
scale = []
start_index = all_notes.index(nada_dasar_value)
scale.append(all_notes[start_index])
current_index = start_index
for interval in intervals:
current_index = (current_index + interval) % len(all_notes)
scale.append(all_notes[current_index])
return scale
# Fungsi untuk mengisi dropdown akord dan menghasilkan skala berdasarkan nada dasar dan pilihan Mayor/Minor
def tampilkan_akord():
global akord_tampil
nada_dasar_value = nada_dasar_dropdown.get()
Mayor_minor_value = Mayor_minor_dropdown.get()
# Tentukan interval berdasarkan pilihan Mayor atau Minor
if Mayor_minor_value == "Mayor":
intervals = skala_mayor
progresi = ["", "m", "m", "", "", "m", "dim"]
else:
intervals = skala_minor
progresi = ["m", "dim", "", "m", "m", "", ""]
# Dapatkan skala berdasarkan nada dasar dan interval
generated_scale = generate_scale(nada_dasar_value, intervals)
# Buat daftar akord
akord_list = []
for i, nada in enumerate(generated_scale[:-1]): # Exclude the octave note
akord = nada + progresi[i]
akord_list.append(akord)
# Set the values of combobox_akord
combobox_akord['values'] = akord_list
combobox_akord.set('') # Reset selection
akord_tampil = True # Set flag menjadi True ketika tombol ditekan
messagebox.showinfo("Info", "Lanjutkan ke combobox Pilih Akord \nuntuk memilih akord") # Menampilkan pesan
# Fungsi untuk memasukkan akord yang dipilih ke dalam output_text
def insert_selected_akord(event):
if not akord_tampil: # Jika belum menekan tombol Tampilkan Akord
messagebox.showwarning("Peringatan", "Sebelumnya tekan tombol Tampilkan Akord")
return
selected_akord = combobox_akord.get()
# Menyisipkan akord di posisi kursor saat ini
current_index = output_text.index(tk.INSERT) # Dapatkan posisi kursor
output_text.insert(current_index, f"{selected_akord} ")
# Fungsi untuk memasukkan simbol notasi yang dipilih ke partitur
def insert_symbol(symbol):
output_text.insert(tk.INSERT, symbol)
# Fungsi untuk memasukkan akord ke partitur, di atas angka nada
def insert_chord(chord):
output_text.insert(tk.INSERT, chord, ("superscript", "chord_color"))
output_text.insert(tk.INSERT, "")
# Simbol notasi yang akan digunakan (tambahkan nada panjang satu, dua, dan tiga ketuk)
symbol_options = [
"•", "••", "•••", "\u007C", "||", ":||", "/", "\\", "'",
"0", "♯", "♭", "\u2323", "\u0305", "\u0818", "\u07EB", "\u135E", "\u135F", "\u135D", "\u1A18", "\u0324", "\u1CDF", "" # Nada panjang satu, dua, dan tiga ketuk
]
# Entry Nada Dasar
mayor_minor = ["Mayor", "minor"]
# Entry Nilai Nada Dasar
nada_dasar = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "Db", "Eb", "Gb", "Ab", "Bb"]
# Akord Mayor dan Minor
akord_mayor = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
akord_minor = ["Am", "A#m", "Bm", "Cm", "C#m", "Dm", "D#m", "Em", "Fm", "F#m","Gm", "G#m"]
# Fungsi untuk memasukkan nada ke partitur pada posisi tertentu
def insert_note(note):
current_content = output_text.get("1.0", tk.INSERT)
lines = current_content.split("\n")
# Cari baris terakhir birama
last_birama_line_index = None
for i, line in enumerate(reversed(lines)):
if "|" in line: # Cek untuk birama
last_birama_line_index = len(lines) - i - 1
break
# Pindah ke baris baru jika nada terlalu panjang untuk satu birama
if last_birama_line_index is not None:
if len(lines[last_birama_line_index]) + len(note) > 30: # Contoh batas maksimal birama
output_text.insert(tk.INSERT, f"\n{create_birama_template()}|\nLirik: \n\n")
output_text.insert(tk.INSERT, note)
# Fungsi untuk membuat template birama
def create_birama_template():
template = "| | | | | | | | | | | | | | | | | | | |" # Garis birama 4/4
return template
# Fungsi untuk menambahkan birama ke output_text dengan pembatas di akhir
def add_birama():
birama = create_birama_template()
output_text.insert(tk.END, f"{birama}|\n") # Baris pertama: birama untuk nada (dengan pembatas di akhir)
output_text.insert(tk.END, "Lirik: " + " " * (len(birama) - 7) + "|\n") # Baris kedua: tempat lirik (dengan pembatas di akhir)
output_text.insert(tk.END, "\n") # Baris ketiga: separator kosong untuk jarak antar birama
# Membuat canvas untuk konten partitur
output_text_canvas = tk.Canvas(root)
output_text_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# Scrollbars untuk canvas
scrollbar_y = tk.Scrollbar(root, orient=tk.VERTICAL, command=output_text_canvas.yview)
scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
scrollbar_x = tk.Scrollbar(root, orient=tk.HORIZONTAL, command=output_text_canvas.xview)
scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
output_text_canvas.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
output_text_canvas.bind('<Configure>', lambda e: output_text_canvas.configure(scrollregion=output_text_canvas.bbox('all')))
# Membuat frame untuk konten di dalam canvas
output_frame = tk.Frame(output_text_canvas)
output_text_canvas.create_window((0, 0), window=output_frame, anchor="nw")
# Membuat kotak untuk tombol simbol notasi
symbol_frame = tk.Frame(output_frame)
symbol_frame.grid(row=0, column=0, pady=5)
# Label instruksi simbol
symbol_label = tk.Label(symbol_frame, text="Simbol Notasi Angka:")
symbol_label.grid(row=0, column=0, columnspan=6, pady=(0, 5))
# Loop untuk membuat tombol untuk setiap simbol
for i, symbol in enumerate(symbol_options):
button = tk.Button(symbol_frame, text=symbol, width=2, command=lambda s=symbol: insert_symbol(s))
button.grid(row=1 + i // 8, column=i % 8, padx=5, pady=5)
# Frame untuk dropdown akord
chord_frame = tk.Frame(output_frame)
chord_frame.grid(row=1, column=0, pady=5)
# Entry Nada Dasar (Dropdown)
nada_dasar_label = tk.Label(chord_frame, text="Nada Dasar Lagu:")
nada_dasar_label.grid(row=0, column=1, padx=1, pady=5)
# Dropdown untuk Mayor/Minor
Mayor_minor_dropdown = ttk.Combobox(chord_frame, values=["Mayor", "minor"], state="readonly")
Mayor_minor_dropdown.grid(row=0, column=2, padx=(1, 2), pady=5)
Mayor_minor_dropdown.set("Mayor") # Default ke "Mayor"
do_label = tk.Label(chord_frame, text="1 = ", width=4, anchor="e", font=("Helvetica", 12, "bold"))
do_label.grid(row=0, column=3, padx=(0, 1), pady=5) # Kurangi padding kiri ke 0
# Dropdown untuk Nilai Nada Dasar
nada_dasar_dropdown = ttk.Combobox(chord_frame, values=nada_dasar, state="readonly")
nada_dasar_dropdown.grid(row=0, column=4, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
nada_dasar_dropdown.set("C") # Default Nada Dasar diatur ke "C"
# Tombol untuk menampilkan akord
button_tampilkan_akord = tk.Button(chord_frame, text="Tampilkan Akord", command=tampilkan_akord)
button_tampilkan_akord.grid(row=1, column=1, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
# Combobox untuk pilihan akord
akord_label = tk.Label(chord_frame, text="Pilih Akord:")
akord_label.grid(row=1, column=2, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
combobox_akord = ttk.Combobox(chord_frame, state="readonly")
combobox_akord.grid(row=1, column=3, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
combobox_akord.bind("<<ComboboxSelected>>", insert_selected_akord)
# Fungsi untuk menampilkan partitur dengan indentasi
def show_partitur():
output_text.delete(1.0, tk.END)
output_text.insert(tk.END, "\nPartitur Notasi Angka :\n", "indent")
output_text.insert(tk.END, f"Judul Lagu : \n", "indent")
output_text.insert(tk.END, f"Nada Dasar : \n", "indent")
output_text.insert(tk.END, f"Tanda Birama : \n", "indent")
output_text.insert(tk.END, f"Pencipta : \n", "indent")
output_text.insert(tk.END, f"Arranger : \n", "indent")
output_text.insert(tk.END, "\nArah/Arus Musik :\n", "indent")
output_text.insert(tk.END, "Tempo (BPM) :\n", "indent")
output_text.insert(tk.END, " \n \n", "indent")
output_text.insert(tk.END, create_birama_template() + "\n")
output_text.insert(tk.END, "Lirik: " + "\n") # Baris kedua: tempat lirik (dengan pembatas di akhir)
output_text.insert(tk.END, "\n") # Baris ketiga: separator kosong untuk jarak antar birama
# Menonaktifkan tombol setelah ditekan
show_button.config(state=tk.DISABLED, bg="lightgrey", text="Tombol Tidak Aktif")
# Fungsi untuk mengaktifkan kembali tombol Tampil Partitur
def reset_button():
show_button.config(state=tk.NORMAL, bg="grey", text="Tampil Partitur")
# Fungsi untuk menyimpan perubahan
def save_partitur():
edited_text = output_text.get(1.0, tk.END).strip()
file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text Files", "*.txt")])
if file_path:
try:
with open(file_path, 'w') as file:
file.write(edited_text)
messagebox.showinfo("Sukses", "Partitur berhasil disimpan.")
except Exception as e:
messagebox.showerror("Error", f"Gagal menyimpan partitur: {e}")
# Fungsi untuk membuka file partitur
def open_partitur():
file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt"), ("All files", "*.*")])
if file_path:
with open(file_path, "r") as file:
content = file.read()
output_text.delete(1.0, tk.END)
output_text.insert(tk.END, content)
# Tombol untuk menampilkan partitur
show_button = tk.Button(output_frame, text="Tampil Partitur", bg="grey", fg="white", command=show_partitur)
show_button.grid(row=7, column=0, padx=5, pady=5)
# Tombol untuk mengaktifkan kembali tombol Tampil Partitur
reset_button = tk.Button(output_frame, text="Reset", bg="blue", fg="white", command=reset_button)
reset_button.grid(row=7, column=1, padx=5, pady=5)
# Fungsi untuk memasukkan nada ke partitur di posisi kursor
def paste_gn():
try:
with open("temp_gn_value.txt", "r") as temp_file:
gn_value = temp_file.read()
current_index = output_text.index(tk.INSERT)
output_text.insert(current_index, gn_value)
except FileNotFoundError:
output_text.insert(tk.INSERT, "Tidak ada data yang dicopy.")
# Tombol untuk mem-paste gugus nada ke output_text
paste_gn_button = tk.Button(output_frame, text="Paste Gn", bg="grey", fg="white", command=paste_gn)
paste_gn_button.grid(row=8, column=0, padx=5, pady=5)
# Tombol untuk menyimpan partitur
save_button = tk.Button(output_frame, text="Simpan Partitur", bg="grey", fg="white", command=save_partitur)
save_button.grid(row=7, column=2, padx=5, pady=5)
# Tombol untuk membuka partitur
open_button = tk.Button(output_frame, text="Buka Partitur", bg="grey", fg="white",command=open_partitur)
open_button.grid(row=7, column=3, padx=5, pady=5)
# Tombol untuk menambahkan birama
add_birama_button = tk.Button(output_frame, text="Tambah Birama", bg="grey", fg="white", command=add_birama)
add_birama_button.grid(row=8, column=1, padx=5, pady=5)
# Label instruksi di atas output_text
instruksi_label = tk.Label(output_frame, text="Partitur Notasi Angka (Edit di bawah sini):")
instruksi_label.grid(row=9, column=0, padx=5, pady=5)
# Membuat Text Widget untuk output
output_text = tk.Text(output_frame, wrap=tk.WORD, undo=True, width=80, height=50)
output_text.grid(row=10, column=0, columnspan=3, padx=10, pady=10)
# Menambahkan Scrollbars ke Text Widget
output_text_scroll_y = tk.Scrollbar(output_frame, orient=tk.VERTICAL, command=output_text.yview)
output_text_scroll_y.grid(row=9, column=3, sticky="ns")
output_text['yscrollcommand'] = output_text_scroll_y.set
output_text_scroll_x = tk.Scrollbar(output_frame, orient=tk.HORIZONTAL, command=output_text.xview)
output_text_scroll_x.grid(row=10, column=0, columnspan=3, sticky="we")
output_text['xscrollcommand'] = output_text_scroll_x.set
# Menambah gaya (style) pada text untuk superscript
output_text.tag_configure("superscript", offset=5)
output_text.tag_configure("chord_color", foreground="blue")
output_text.tag_configure("indent", lmargin1=10, lmargin2=10)
# Fungsi untuk menyimpan sementara gugus nada ke dalam file sementara
def copy_gn():
try:
selected_text = output_text.get(tk.SEL_FIRST, tk.SEL_LAST)
with open("temp_gn_value.txt", "w") as temp_file:
temp_file.write(selected_text)
messagebox.showinfo("Sukses", "Gugus Nada berhasil disalin.")
except tk.TclError:
messagebox.showwarning("Peringatan", "Tidak ada teks yang disalin.")
# Tombol untuk menyalin gugus nada ke file sementara
copy_gn_button = tk.Button(output_frame, text="Salin Gn", bg="grey", fg="white", command=copy_gn)
copy_gn_button.grid(row=8, column=2, padx=5, pady=5)
# Fungsi untuk keluar dari aplikasi
def exit_app():
result = messagebox.askquestion("Keluar", "Apakah Anda yakin ingin keluar?", icon="warning")
if result == 'yes':
root.quit()
# Tombol untuk keluar dari aplikasi
exit_button = tk.Button(output_frame, text="Keluar", bg="red", fg="white", command=exit_app)
exit_button.grid(row=11, column=2, padx=10, pady=10)
# Fungsi utama untuk menjalankan aplikasi
def main():
root.mainloop()
# Memanggil fungsi utama
if __name__ == "__main__":
main()
Pastikan setiap elemen dan fungsi tidak ada yang ganda atau duplikat. Berikan saya hasilnya berupa kode yang lengkap yang benar dan tanpa error, untuk melengkapi file partitur_notasi_angka.py
Untuk menggabungkan kedua kode tersebut, kita akan mengintegrasikan bagian pertama (yang menampilkan partitur dan interaksi birama) ke dalam struktur tkinter yang sudah diatur dalam bagian kedua. Berikut adalah hasil gabungannya:
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk
# Setup UI
root = tk.Tk()
root.geometry("690x1390")
root.title("Partitur Notasi Angka dengan Font Khusus")
# Skala Mayor dan Minor
skala_mayor = [2, 2, 1, 2, 2, 2, 1]
skala_minor = [2, 1, 2, 2, 1, 2, 2]
akord_tampil = False # Flag untuk mengecek apakah tombol "Tampilkan Akord" sudah ditekan
# Fungsi untuk mengubah nada berdasarkan interval
def generate_scale(nada_dasar_value, intervals):
all_notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
scale = []
start_index = all_notes.index(nada_dasar_value)
scale.append(all_notes[start_index])
current_index = start_index
for interval in intervals:
current_index = (current_index + interval) % len(all_notes)
scale.append(all_notes[current_index])
return scale
# Fungsi untuk mengisi dropdown akord dan menghasilkan skala berdasarkan nada dasar dan pilihan Mayor/Minor
def tampilkan_akord():
global akord_tampil
nada_dasar_value = nada_dasar_dropdown.get()
Mayor_minor_value = Mayor_minor_dropdown.get()
# Tentukan interval berdasarkan pilihan Mayor atau Minor
if Mayor_minor_value == "Mayor":
intervals = skala_mayor
progresi = ["", "m", "m", "", "", "m", "dim"]
else:
intervals = skala_minor
progresi = ["m", "dim", "", "m", "m", "", ""]
# Dapatkan skala berdasarkan nada dasar dan interval
generated_scale = generate_scale(nada_dasar_value, intervals)
# Buat daftar akord
akord_list = []
for i, nada in enumerate(generated_scale[:-1]): # Exclude the octave note
akord = nada + progresi[i]
akord_list.append(akord)
# Set the values of combobox_akord
combobox_akord['values'] = akord_list
combobox_akord.set('') # Reset selection
akord_tampil = True # Set flag menjadi True ketika tombol ditekan
messagebox.showinfo("Info", "Lanjutkan ke combobox Pilih Akord \nuntuk memilih akord") # Menampilkan pesan
# Fungsi untuk memasukkan akord yang dipilih ke dalam output_text
def insert_selected_akord(event):
if not akord_tampil: # Jika belum menekan tombol Tampilkan Akord
messagebox.showwarning("Peringatan", "Sebelumnya tekan tombol Tampilkan Akord")
return
selected_akord = combobox_akord.get()
# Menyisipkan akord di posisi kursor saat ini
current_index = output_text.index(tk.INSERT) # Dapatkan posisi kursor
output_text.insert(current_index, f"{selected_akord} ")
# Fungsi untuk memasukkan simbol notasi yang dipilih ke partitur
def insert_symbol(symbol):
output_text.insert(tk.INSERT, symbol)
# Fungsi untuk memasukkan akord ke partitur, di atas angka nada
def insert_chord(chord):
output_text.insert(tk.INSERT, chord, ("superscript", "chord_color"))
output_text.insert(tk.INSERT, "")
# Simbol notasi yang akan digunakan (tambahkan nada panjang satu, dua, dan tiga ketuk)
symbol_options = [
"•", "••", "•••", "\u007C", "||", ":||", "/", "\\", "'",
"0", "♯", "♭", "\u2323", "\u0305", "\u0818", "\u07EB", "\u135E", "\u135F", "\u135D", "\u1A18", "\u0324", "\u1CDF", "" # Nada panjang satu, dua, dan tiga ketuk
]
# Entry Nada Dasar
mayor_minor = ["Mayor", "minor"]
# Entry Nilai Nada Dasar
nada_dasar = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "Db", "Eb", "Gb", "Ab", "Bb"]
# Akord Mayor dan Minor
akord_mayor = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
akord_minor = ["Am", "A#m", "Bm", "Cm", "C#m", "Dm", "D#m", "Em", "Fm", "F#m","Gm", "G#m"]
# Fungsi untuk memasukkan nada ke partitur pada posisi tertentu
def insert_note(note):
current_content = output_text.get("1.0", tk.INSERT)
lines = current_content.split("\n")
# Cari baris terakhir birama
last_birama_line_index = None
for i, line in enumerate(reversed(lines)):
if "|" in line: # Cek untuk birama
last_birama_line_index = len(lines) - i - 1
break
# Pindah ke baris baru jika nada terlalu panjang untuk satu birama
if last_birama_line_index is not None:
if len(lines[last_birama_line_index]) + len(note) > 30: # Contoh batas maksimal birama
output_text.insert(tk.INSERT, f"\n{create_birama_template()}|\nLirik: \n\n")
output_text.insert(tk.INSERT, note)
# Fungsi untuk membuat template birama
def create_birama_template():
template = "| | | | | | | | | | | | | | | | | | | |" # Garis birama 4/4
return template
# Fungsi untuk menambahkan birama ke output_text dengan pembatas di akhir
def add_birama():
birama = create_birama_template()
output_text.insert(tk.END, f"{birama}|\n") # Baris pertama: birama untuk nada (dengan pembatas di akhir)
output_text.insert(tk.END, "Lirik: " + " " * (len(birama) - 7) + "|\n") # Baris kedua: tempat lirik (dengan pembatas di akhir)
output_text.insert(tk.END, "\n") # Baris ketiga: separator kosong untuk jarak antar birama
# Fungsi untuk menampilkan partitur dengan indentasi
def show_partitur():
output_text.delete(1.0, tk.END) # Hapus konten sebelumnya
output_text.insert(tk.END, "Berikut adalah template partitur dengan birama 4/4:\n\n")
output_text.insert(tk.END, create_birama_template() + "\n")
output_text.insert(tk.END, "Lirik: " + " " * (len(create_birama_template()) - 7) + "|\n\n")
# Membuat canvas untuk konten partitur
output_text_canvas = tk.Canvas(root)
output_text_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# Scrollbars untuk canvas
scrollbar_y = tk.Scrollbar(root, orient=tk.VERTICAL, command=output_text_canvas.yview)
scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
scrollbar_x = tk.Scrollbar(root, orient=tk.HORIZONTAL, command=output_text_canvas.xview)
scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
output_text_canvas.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
output_text_canvas.bind('<Configure>', lambda e: output_text_canvas.configure(scrollregion=output_text_canvas.bbox('all')))
# Membuat frame untuk konten di dalam canvas
output_frame = tk.Frame(output_text_canvas)
output_text_canvas.create_window((0, 0), window=output_frame, anchor="nw")
# Kotak teks untuk output partitur
output_text = tk.Text(output_frame, wrap="none", width=80, height=40, undo=True, font=("Courier", 12))
output_text.grid(row=2, column=0, padx=10, pady=5)
# Tombol untuk menambah birama baru
button_add_birama = tk.Button(output_frame, text="Tambah Birama", command=add_birama)
button_add_birama.grid(row=1, column=4, padx=(1, 2), pady=5)
# Tombol untuk menampilkan template partitur
button_show_partitur = tk.Button(output_frame, text="Tampilkan Partitur", command=show_partitur)
button_show_partitur.grid(row=1, column=5, padx=(1,
# Dropdown untuk Nada Dasar
nada_dasar_dropdown = ttk.Combobox(chord_frame, values=nada_dasar)
nada_dasar_dropdown.grid(row=0, column=2, padx=1, pady=5)
# Dropdown untuk Mayor/Minor
Mayor_minor_label = tk.Label(chord_frame, text="Mayor/Minor:")
Mayor_minor_label.grid(row=0, column=3, padx=1, pady=5)
Mayor_minor_dropdown = ttk.Combobox(chord_frame, values=mayor_minor)
Mayor_minor_dropdown.grid(row=0, column=4, padx=1, pady=5)
# Tombol untuk menampilkan skala akord berdasarkan nada dasar dan Mayor/Minor
button_generate_akord = tk.Button(chord_frame, text="Tampilkan Akord", command=tampilkan_akord)
button_generate_akord.grid(row=0, column=5, padx=(1, 2), pady=5)
# Combobox untuk menampilkan akord yang dihasilkan
combobox_akord = ttk.Combobox(chord_frame)
combobox_akord.grid(row=1, column=2, padx=1, pady=5)
combobox_akord.bind("<<ComboboxSelected>>", insert_selected_akord)
# Kotak teks untuk output partitur
output_text = tk.Text(output_frame, wrap="none", width=80, height=40, undo=True, font=("Courier", 12))
output_text.grid(row=2, column=0, padx=10, pady=5)
# Tombol untuk menambah birama baru
button_add_birama = tk.Button(chord_frame, text="Tambah Birama", command=add_birama)
button_add_birama.grid(row=1, column=4, padx=(1, 2), pady=5)
# Tombol untuk menampilkan template partitur
button_show_partitur = tk.Button(chord_frame, text="Tampilkan Partitur", command=show_partitur)
button_show_partitur.grid(row=1, column=5, padx=(1, 2), pady=5)
# Configure tags for text styling
output_text.tag_configure("superscript", offset=8) # Superscript untuk chord
output_text.tag_configure("chord_color", foreground="blue") # Warna biru untuk chord
# Menambahkan scrollbar ke Text Widget
output_text_scrollbar_y = tk.Scrollbar(output_frame, orient=tk.VERTICAL, command=output_text.yview)
output_text_scrollbar_y.grid(row=2, column=1, sticky='ns')
output_text.configure(yscrollcommand=output_text_scrollbar_y.set)
output_text_scrollbar_x = tk.Scrollbar(output_frame, orient=tk.HORIZONTAL, command=output_text.xview)
output_text_scrollbar_x.grid(row=3, column=0, sticky='ew')
output_text.configure(xscrollcommand=output_text_scrollbar_x.set)
# Fungsi untuk membuat template birama
def create_birama_template():
template = "| | | | | | | | | | | | | | | | | | | |" # Garis birama 4/4
return template
# Fungsi untuk menambah birama baru
def add_birama():
birama = create_birama_template()
output_text.insert(tk.END, f"{birama}|\n") # Baris pertama: birama untuk nada (dengan pembatas di akhir)
output_text.insert(tk.END, "Lirik: " + " " * (len(birama) - 7) + "|\n") # Baris kedua: tempat lirik (dengan pembatas di akhir)
output_text.insert(tk.END, "\n") # Baris ketiga: separator kosong untuk jarak antar birama
# Fungsi untuk menampilkan partitur dengan indentasi
def show_partitur():
output_text.delete(1.0, tk.END) # Hapus konten sebelumnya
output_text.insert(tk.END, "Berikut adalah template partitur dengan birama 4/4:\n\n")
output_text.insert(tk.END, create_birama_template() + "\n")
output_text.insert(tk.END, "Lirik: " + " " * (len(create_birama_template()) - 7) + "|\n\n")
# Fungsi untuk memasukkan simbol yang dipilih ke partitur
def insert_symbol(symbol):
output_text.insert(tk.INSERT, symbol)
# Simbol notasi yang akan digunakan (tambahkan nada panjang satu, dua, dan tiga ketuk)
symbol_options = [
"•", "••", "•••", "|", "||", ":||", "/", "\\", "'", "0", "♯", "♭", "\u2323", "\u0305", "\u0818", "\u07EB", "\u135E", "\u135F", "\u135D", "\u1A18", "\u0324", "\u1CDF"
]
# Membuat kotak untuk tombol simbol notasi
symbol_frame = tk.Frame(output_frame)
symbol_frame.grid(row=0, column=0, pady=5)
# Label instruksi simbol
symbol_label = tk.Label(symbol_frame, text="Simbol Notasi Angka:")
symbol_label.grid(row=0, column=0, columnspan=6, pady=(0, 5))
# Loop untuk membuat tombol untuk setiap simbol
for i, symbol in enumerate(symbol_options):
button = tk.Button(symbol_frame, text=symbol, width=2, command=lambda s=symbol: insert_symbol(s))
button.grid(row=1 + i // 8, column=i % 8, padx=5, pady=5)
# Membuat frame untuk konten di dalam canvas
output_frame = tk.Frame(output_text_canvas)
output_text_canvas.create_window((0, 0), window=output_frame, anchor="nw")
# Scrollbars untuk canvas
scrollbar_y = tk.Scrollbar(root, orient=tk.VERTICAL, command=output_text_canvas.yview)
scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
scrollbar_x = tk.Scrollbar(root, orient=tk.HORIZONTAL, command=output_text_canvas.xview)
scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
output_text_canvas.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
output_text_canvas.bind('<Configure>', lambda e: output_text_canvas.configure(scrollregion=output_text_canvas.bbox('all')))
# Run the Tkinter main loop
root.mainloop()
Kode ini telah digabungkan dengan komponen untuk menampilkan partitur, memilih nada dasar, menambahkan birama, dan simbol notasi dengan dukungan scrollbars. Kombinasi ini memberikan tampilan interaktif untuk membuat partitur notasi angka menggunakan Tkinter.
Sehingga jadilah Kode selengkapnya untuk file partitur_notasi_angka.py adalah berikut ini:
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk
# Setup UI
root = tk.Tk()
root.geometry("690x1390")
root.title("Partitur Notasi Angka dengan Font Khusus")
# Skala Mayor dan Minor
skala_mayor = [2, 2, 1, 2, 2, 2, 1]
skala_minor = [2, 1, 2, 2, 1, 2, 2]
akord_tampil = False # Flag untuk mengecek apakah tombol "Tampilkan Akord" sudah ditekan
# Fungsi untuk mengubah nada berdasarkan interval
def generate_scale(nada_dasar_value, intervals):
all_notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
scale = []
start_index = all_notes.index(nada_dasar_value)
scale.append(all_notes[start_index])
current_index = start_index
for interval in intervals:
current_index = (current_index + interval) % len(all_notes)
scale.append(all_notes[current_index])
return scale
# Fungsi untuk mengisi dropdown akord dan menghasilkan skala berdasarkan nada dasar dan pilihan Mayor/Minor
def tampilkan_akord():
global akord_tampil
nada_dasar_value = nada_dasar_dropdown.get()
Mayor_minor_value = Mayor_minor_dropdown.get()
# Tentukan interval berdasarkan pilihan Mayor atau Minor
if Mayor_minor_value == "Mayor":
intervals = skala_mayor
progresi = ["", "m", "m", "", "", "m", "dim"]
else:
intervals = skala_minor
progresi = ["m", "dim", "", "m", "m", "", ""]
# Dapatkan skala berdasarkan nada dasar dan interval
generated_scale = generate_scale(nada_dasar_value, intervals)
# Buat daftar akord
akord_list = []
for i, nada in enumerate(generated_scale[:-1]): # Exclude the octave note
akord = nada + progresi[i]
akord_list.append(akord)
# Set the values of combobox_akord
combobox_akord['values'] = akord_list
combobox_akord.set('') # Reset selection
akord_tampil = True # Set flag menjadi True ketika tombol ditekan
messagebox.showinfo("Info", "Lanjutkan ke combobox Pilih Akord \nuntuk memilih akord") # Menampilkan pesan
# Fungsi untuk memasukkan akord yang dipilih ke dalam output_text
def insert_selected_akord(event):
if not akord_tampil: # Jika belum menekan tombol Tampilkan Akord
messagebox.showwarning("Peringatan", "Sebelumnya tekan tombol Tampilkan Akord")
return
selected_akord = combobox_akord.get()
# Menyisipkan akord di posisi kursor saat ini
current_index = output_text.index(tk.INSERT) # Dapatkan posisi kursor
output_text.insert(current_index, f"{selected_akord} ")
# Fungsi untuk memasukkan simbol notasi yang dipilih ke partitur
def insert_symbol(symbol):
output_text.insert(tk.INSERT, symbol)
# Fungsi untuk memasukkan akord ke partitur, di atas angka nada
def insert_chord(chord):
output_text.insert(tk.INSERT, chord, ("superscript", "chord_color"))
output_text.insert(tk.INSERT, "")
# Simbol notasi yang akan digunakan (tambahkan nada panjang satu, dua, dan tiga ketuk)
symbol_options = [
"•", "••", "•••", "\u007C", "||", ":||", "/", "\\", "'",
"0", "♯", "♭", "\u2323", "\u0305", "\u0818", "\u07EB", "\u135E", "\u135F", "\u135D", "\u1A18", "\u0324", "\u1CDF", "" # Nada panjang satu, dua, dan tiga ketuk
]
# Entry Nada Dasar
mayor_minor = ["Mayor", "minor"]
# Entry Nilai Nada Dasar
nada_dasar = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "Db", "Eb", "Gb", "Ab", "Bb"]
# Akord Mayor dan Minor
akord_mayor = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
akord_minor = ["Am", "A#m", "Bm", "Cm", "C#m", "Dm", "D#m", "Em", "Fm", "F#m","Gm", "G#m"]
# Fungsi untuk memasukkan nada ke partitur pada posisi tertentu
def insert_note(note):
current_content = output_text.get("1.0", tk.INSERT)
lines = current_content.split("\n")
# Cari baris terakhir birama
last_birama_line_index = None
for i, line in enumerate(reversed(lines)):
if "|" in line: # Cek untuk birama
last_birama_line_index = len(lines) - i - 1
break
# Pindah ke baris baru jika nada terlalu panjang untuk satu birama
if last_birama_line_index is not None:
if len(lines[last_birama_line_index]) + len(note) > 30: # Contoh batas maksimal birama
output_text.insert(tk.INSERT, f"\n{create_birama_template()}|\nLirik: \n\n")
output_text.insert(tk.INSERT, note)
# Fungsi untuk membuat template birama
def create_birama_template():
template = "| | | | | | | | | | | | | | | | | | | |" # Garis birama 4/4
return template
# Fungsi untuk menambahkan birama ke output_text dengan pembatas di akhir
def add_birama():
birama = create_birama_template()
output_text.insert(tk.END, f"{birama}|\n") # Baris pertama: birama untuk nada (dengan pembatas di akhir)
output_text.insert(tk.END, "Lirik: " + " " * (len(birama) - 7) + "|\n") # Baris kedua: tempat lirik (dengan pembatas di akhir)
output_text.insert(tk.END, "\n") # Baris ketiga: separator kosong untuk jarak antar birama
# Membuat canvas untuk konten partitur
output_text_canvas = tk.Canvas(root)
output_text_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# Scrollbars untuk canvas
scrollbar_y = tk.Scrollbar(root, orient=tk.VERTICAL, command=output_text_canvas.yview)
scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
scrollbar_x = tk.Scrollbar(root, orient=tk.HORIZONTAL, command=output_text_canvas.xview)
scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
output_text_canvas.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
output_text_canvas.bind('<Configure>', lambda e: output_text_canvas.configure(scrollregion=output_text_canvas.bbox('all')))
# Membuat frame untuk konten di dalam canvas
output_frame = tk.Frame(output_text_canvas)
output_text_canvas.create_window((0, 0), window=output_frame, anchor="nw")
# Membuat kotak untuk tombol simbol notasi
symbol_frame = tk.Frame(output_frame)
symbol_frame.grid(row=0, column=0, pady=5)
# Label instruksi simbol
symbol_label = tk.Label(symbol_frame, text="Simbol Notasi Angka:")
symbol_label.grid(row=0, column=0, columnspan=6, pady=(0, 5))
# Loop untuk membuat tombol untuk setiap simbol
for i, symbol in enumerate(symbol_options):
button = tk.Button(symbol_frame, text=symbol, width=2, command=lambda s=symbol: insert_symbol(s))
button.grid(row=1 + i // 8, column=i % 8, padx=5, pady=5)
# Frame untuk dropdown akord
chord_frame = tk.Frame(output_frame)
chord_frame.grid(row=1, column=0, pady=5)
# Entry Nada Dasar (Dropdown)
nada_dasar_label = tk.Label(chord_frame, text="Nada Dasar Lagu:")
nada_dasar_label.grid(row=0, column=1, padx=1, pady=5)
# Dropdown untuk Mayor/Minor
Mayor_minor_dropdown = ttk.Combobox(chord_frame, values=["Mayor", "minor"], state="readonly")
Mayor_minor_dropdown.grid(row=0, column=2, padx=(1, 2), pady=5)
Mayor_minor_dropdown.set("Mayor") # Default ke "Mayor"
do_label = tk.Label(chord_frame, text="1 = ", width=4, anchor="e", font=("Helvetica", 12, "bold"))
do_label.grid(row=0, column=3, padx=(0, 1), pady=5) # Kurangi padding kiri ke 0
# Dropdown untuk Nilai Nada Dasar
nada_dasar_dropdown = ttk.Combobox(chord_frame, values=nada_dasar, state="readonly")
nada_dasar_dropdown.grid(row=0, column=4, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
nada_dasar_dropdown.set("C") # Default Nada Dasar diatur ke "C"
# Tombol untuk menampilkan akord
button_tampilkan_akord = tk.Button(chord_frame, text="Tampilkan Akord", command=tampilkan_akord)
button_tampilkan_akord.grid(row=1, column=1, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
# Combobox untuk pilihan akord
akord_label = tk.Label(chord_frame, text="Pilih Akord:")
akord_label.grid(row=1, column=2, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
combobox_akord = ttk.Combobox(chord_frame, state="readonly")
combobox_akord.grid(row=1, column=3, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
combobox_akord.bind("<<ComboboxSelected>>", insert_selected_akord)
# Fungsi untuk menampilkan partitur dengan indentasi
def show_partitur():
output_text.delete(1.0, tk.END)
output_text.insert(tk.END, "\nPartitur Notasi Angka :\n", "indent")
output_text.insert(tk.END, f"Judul Lagu : \n", "indent")
output_text.insert(tk.END, f"Nada Dasar : \n", "indent")
output_text.insert(tk.END, f"Tanda Birama : \n", "indent")
output_text.insert(tk.END, f"Pencipta : \n", "indent")
output_text.insert(tk.END, f"Arranger : \n", "indent")
output_text.insert(tk.END, "\nArah/Arus Musik :\n", "indent")
output_text.insert(tk.END, "Tempo (BPM) :\n", "indent")
output_text.insert(tk.END, " \n \n", "indent")
output_text.insert(tk.END, create_birama_template() + "\n")
output_text.insert(tk.END, "Lirik: " + " " * (len(create_birama_template()) - 7) + "|\n\n") # Baris kedua: tempat lirik (dengan pembatas di akhir)
output_text.insert(tk.END, "\n") # Baris ketiga: separator kosong untuk jarak antar birama
# Menonaktifkan tombol setelah ditekan
show_partitur_button.config(state=tk.DISABLED, bg="lightgrey", text="Tombol Tidak Aktif")
# Fungsi untuk mengaktifkan kembali tombol Tampil Partitur
def reset_button():
show_button.config(state=tk.NORMAL, bg="grey", text="Tampil Partitur")
# Fungsi untuk menyimpan perubahan
def save_partitur():
edited_text = output_text.get(1.0, tk.END).strip()
file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text Files", "*.txt")])
if file_path:
try:
with open(file_path, 'w') as file:
file.write(edited_text)
messagebox.showinfo("Sukses", "Partitur berhasil disimpan.")
except Exception as e:
messagebox.showerror("Error", f"Gagal menyimpan partitur: {e}")
# Fungsi untuk membuka file partitur
def open_partitur():
file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt"), ("All files", "*.*")])
if file_path:
with open(file_path, "r") as file:
content = file.read()
output_text.delete(1.0, tk.END)
output_text.insert(tk.END, content)
# Tombol untuk menampilkan partitur
show_partitur_button = tk.Button(output_frame, text="Tampil Partitur", bg="grey", fg="white", command=show_partitur)
show_partitur_button.grid(row=7, column=0, padx=(1, 2), pady=5)
# Tombol untuk mengaktifkan kembali tombol Tampil Partitur
reset_button = tk.Button(output_frame, text="Reset", bg="blue", fg="white", command=reset_button)
reset_button.grid(row=7, column=1, padx=5, pady=5)
# Fungsi untuk memasukkan nada ke partitur di posisi kursor
def paste_gn():
try:
with open("temp_gn_value.txt", "r") as temp_file:
gn_value = temp_file.read()
current_index = output_text.index(tk.INSERT)
output_text.insert(current_index, gn_value)
except FileNotFoundError:
output_text.insert(tk.INSERT, "Tidak ada data yang dicopy.")
# Tombol untuk mem-paste gugus nada ke output_text
paste_gn_button = tk.Button(output_frame, text="Paste Gn", bg="grey", fg="white", command=paste_gn)
paste_gn_button.grid(row=8, column=0, padx=5, pady=5)
# Tombol untuk menyimpan partitur
save_button = tk.Button(output_frame, text="Simpan Partitur", bg="grey", fg="white", command=save_partitur)
save_button.grid(row=7, column=2, padx=5, pady=5)
# Tombol untuk membuka partitur
open_button = tk.Button(output_frame, text="Buka Partitur", bg="grey", fg="white",command=open_partitur)
open_button.grid(row=7, column=3, padx=5, pady=5)
# Tombol untuk menambahkan birama
add_birama_button = tk.Button(output_frame, text="Tambah Birama", bg="grey", fg="white", command=add_birama)
add_birama_button.grid(row=8, column=1, padx=5, pady=5)
# Label instruksi di atas output_text
instruksi_label = tk.Label(output_frame, text="Partitur Notasi Angka (Edit di bawah sini):")
instruksi_label.grid(row=9, column=0, padx=5, pady=5)
# Membuat Text Widget untuk output
output_text = tk.Text(output_frame, wrap=tk.WORD, undo=True, width=80, height=50, font=("Courier", 10))
output_text.grid(row=10, column=0, columnspan=3, padx=10, pady=10)
# Menambahkan Scrollbars ke Text Widget
output_text_scrollbar_y = tk.Scrollbar(output_frame, orient=tk.VERTICAL, command=output_text.yview)
output_text_scrollbar_y.grid(row=9, column=3, sticky="ns")
output_text.configure(yscrollcommand=output_text_scrollbar_y.set)
output_text_scrollbar_x = tk.Scrollbar(output_frame, orient=tk.HORIZONTAL, command=output_text.xview)
output_text_scrollbar_x.grid(row=10, column=0, columnspan=3, sticky="we")
output_text.configure(xscrollcommand=output_text_scrollbar_x.set)
# Menambah gaya (style) pada text untuk superscript
output_text.tag_configure("superscript", offset=5)
output_text.tag_configure("chord_color", foreground="blue")
output_text.tag_configure("indent", lmargin1=10, lmargin2=10)
# Fungsi untuk menyimpan sementara gugus nada ke dalam file sementara
def copy_gn():
try:
selected_text = output_text.get(tk.SEL_FIRST, tk.SEL_LAST)
with open("temp_gn_value.txt", "w") as temp_file:
temp_file.write(selected_text)
messagebox.showinfo("Sukses", "Gugus Nada berhasil disalin.")
except tk.TclError:
messagebox.showwarning("Peringatan", "Tidak ada teks yang disalin.")
# Tombol untuk menyalin gugus nada ke file sementara
copy_gn_button = tk.Button(output_frame, text="Salin Gn", bg="grey", fg="white", command=copy_gn)
copy_gn_button.grid(row=8, column=2, padx=5, pady=5)
# Fungsi untuk keluar dari aplikasi
def exit_app():
result = messagebox.askquestion("Keluar", "Apakah Anda yakin ingin keluar?", icon="warning")
if result == 'yes':
root.quit()
# Tombol untuk keluar dari aplikasi
exit_button = tk.Button(output_frame, text="Keluar", bg="red", fg="white", command=exit_app)
exit_button.grid(row=11, column=2, padx=10, pady=10)
# Fungsi utama untuk menjalankan aplikasi
def main():
root.mainloop()
# Memanggil fungsi utama
if __name__ == "__main__":
main()
Tapi tampilan output_text kurang menarik karena terlihat adanya pembatas scrollbar horizontal, untuk itu tolong posisikan pembatas scrollbar tersebut pada posisi batas halaman naskah antara halaman 1 dan halaman 2 dan seterusnya, pastikan juga output_text bisa terdiri atas beberapa halaman naskah partitur untuk naskah lagu yang panjang di mana teks nada nadanya yang sangat banyak. Kemudian fungsi output_text.tag_configure("superscript", offset=5) tolong difungsikan dengan benar untuk tampilan kunci akord di posisi superscript dari nada yang dikenai akord.
Untuk memperbaiki tampilan output pada partitur_notasi_angka.py agar lebih menarik dengan posisi scrollbar horizontal di antara batas halaman, dan juga memastikan bahwa teks pada output_text bisa terdiri dari beberapa halaman naskah, serta memperbaiki fungsi tag_configure("superscript", offset=5) untuk menampilkan kunci akord dalam format superscript, berikut langkah-langkah yang bisa diikuti:
1. Menambahkan Scrollbar Horizontal di Batas Halaman Naskah
Untuk membatasi tampilan partitur menjadi beberapa halaman dengan scrollbar horizontal di antara halaman, kamu perlu menyesuaikan tampilan dengan mekanisme paging manual.
Gunakan kontrol layout pada tkinter seperti Canvas untuk membuat pembagian halaman secara lebih jelas dan interaktif.
Text widget mendukung banyak teks, tetapi untuk menampilkan partitur yang sangat panjang dengan batas halaman, bisa menggunakan frame yang berubah-ubah ukurannya ketika halaman bertambah.
Contoh implementasi paging dan scrollbar horizontal:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
# Canvas to simulate multiple pages
canvas = tk.Canvas(root, width=800, height=600)
canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# Create a Scrollbar for the canvas
scrollbar = ttk.Scrollbar(root, orient="vertical", command=canvas.yview)
scrollbar.pack(side=tk.RIGHT, fill="y")
# Scrollbar horizontal untuk bagian halaman
h_scrollbar = ttk.Scrollbar(root, orient="horizontal", command=canvas.xview)
h_scrollbar.pack(side=tk.BOTTOM, fill="x")
# Frame to hold multiple pages inside the canvas
frame = tk.Frame(canvas)
canvas.create_window((0, 0), window=frame, anchor='nw')
# Configure scrolling
frame.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
canvas.configure(yscrollcommand=scrollbar.set, xscrollcommand=h_scrollbar.set)
# Contoh halaman naskah (output_text)
output_text = tk.Text(frame, wrap="none", width=100, height=40)
output_text.pack()
# Simulate multiple pages by adding lots of content
for i in range(5): # Contoh untuk membuat 5 halaman
output_text.insert(tk.END, f"Halaman {i+1} - Teks partitur nada nafa yang sangat banyak.\n\n" * 20)
# Tag configure untuk mengatur superscript
output_text.tag_configure("superscript", offset=5)
# Menambahkan teks dengan akord superscript
output_text.insert(tk.END, "C4", "superscript")
output_text.insert(tk.END, " ")
output_text.insert(tk.END, "D4", "superscript")
root.mainloop()
2. Membuat Output Terdiri atas Beberapa Halaman
Agar output bisa terdiri dari beberapa halaman, gunakan pendekatan berikut:
Setiap halaman diisi dengan sejumlah teks yang terbatas dan tambahkan mekanisme paging (misalnya, tombol Next dan Previous untuk berpindah antar halaman).
Atau, buat scroll secara otomatis menambah halaman ketika teks mencapai batas tertentu.
# Fungsi untuk menambah halaman baru
def add_page():
# Simulate adding a new page
output_text.insert(tk.END, "\n\n--- Halaman Baru ---\n\n")
# Tambahkan teks baru di halaman ini
output_text.insert(tk.END, "Ini adalah halaman baru dengan teks partitur yang banyak.\n")
# Tombol untuk menambah halaman
add_page_button = tk.Button(root, text="Tambah Halaman", command=add_page)
add_page_button.pack()
3. Mengatur Superscript untuk Kunci Akord
Untuk menampilkan kunci akord dalam format superscript, kamu sudah menggunakan tag_configure, tetapi pastikan teks yang diatur tag-nya dengan benar:
Pada output_text, tambahkan tag superscript di teks yang menjadi akord, contohnya seperti di atas:
output_text.insert(tk.END, "C4", "superscript")
Kesimpulan:
Scrollbar horizontal ditempatkan di bawah tampilan partitur dan berfungsi untuk berpindah antar halaman.
Paging diterapkan dengan menggunakan canvas dan window yang mengatur tampilan teks per halaman.
Superscript digunakan dengan benar pada teks akord yang diposisikan di atas teks biasa.
Dengan modifikasi ini, partitur dengan teks nada yang panjang bisa ditampilkan dalam beberapa halaman dan scroll horizontal diatur di antara batas halaman, serta kunci akord tampil dalam format superscript.
Kode yang benar untuk melengkapi isi file partitur_notasi_angka.py adalah berikut ini:
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk
# Setup UI
root = tk.Tk()
root.geometry("690x1390")
root.title("Partitur Notasi Angka dengan Font Khusus")
# Skala Mayor dan Minor
skala_mayor = [2, 2, 1, 2, 2, 2, 1]
skala_minor = [2, 1, 2, 2, 1, 2, 2]
akord_tampil = False # Flag untuk mengecek apakah tombol "Tampilkan Akord" sudah ditekan
# Fungsi untuk mengubah nada berdasarkan interval
def generate_scale(nada_dasar_value, intervals):
all_notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
scale = []
start_index = all_notes.index(nada_dasar_value)
scale.append(all_notes[start_index])
current_index = start_index
for interval in intervals:
current_index = (current_index + interval) % len(all_notes)
scale.append(all_notes[current_index])
return scale
# Fungsi untuk mengisi dropdown akord dan menghasilkan skala berdasarkan nada dasar dan pilihan Mayor/Minor
def tampilkan_akord():
global akord_tampil
nada_dasar_value = nada_dasar_dropdown.get()
Mayor_minor_value = Mayor_minor_dropdown.get()
# Tentukan interval berdasarkan pilihan Mayor atau Minor
if Mayor_minor_value == "Mayor":
intervals = skala_mayor
progresi = ["", "m", "m", "", "", "m", "dim"]
else:
intervals = skala_minor
progresi = ["m", "dim", "", "m", "m", "", ""]
# Dapatkan skala berdasarkan nada dasar dan interval
generated_scale = generate_scale(nada_dasar_value, intervals)
# Buat daftar akord
akord_list = []
for i, nada in enumerate(generated_scale[:-1]): # Exclude the octave note
akord = nada + progresi[i]
akord_list.append(akord)
# Set the values of combobox_akord
combobox_akord['values'] = akord_list
combobox_akord.set('') # Reset selection
akord_tampil = True # Set flag menjadi True ketika tombol ditekan
messagebox.showinfo("Info", "Lanjutkan ke combobox Pilih Akord \nuntuk memilih akord nada") # Menampilkan pesan
# Fungsi untuk memasukkan akord yang dipilih ke dalam output_text
def insert_selected_akord(event):
if not akord_tampil: # Jika belum menekan tombol Tampilkan Akord
messagebox.showwarning("Peringatan", "Sebelumnya tekan tombol Tampilkan Akord")
return
selected_akord = combobox_akord.get()
# Menyisipkan akord di posisi kursor saat ini
current_index = output_text.index(tk.INSERT) # Dapatkan posisi kursor
output_text.insert(current_index, f"{selected_akord} ")
# Fungsi untuk memasukkan simbol notasi yang dipilih ke partitur
def insert_symbol(symbol):
output_text.insert(tk.INSERT, symbol)
# Simbol notasi yang akan digunakan (tambahkan nada panjang satu, dua, dan tiga ketuk)
symbol_options = [
"•", "••", "•••", "\u007C", "||", ":||", "/", "\\", "'",
"0", "♯", "♭", "\u2323", "\u0305", "\u0818", "\u07EB", "\u135E", "\u135F", "\u135D", "\u1A18", "\u0324", "\u1CDF", "" # Nada panjang satu, dua, dan tiga ketuk
]
# Entry Nada Dasar
mayor_minor = ["Mayor", "minor"]
# Entry Nilai Nada Dasar
nada_dasar = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "Db", "Eb", "Gb", "Ab", "Bb"]
# Akord Mayor dan Minor
akord_mayor = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
akord_minor = ["Am", "A#m", "Bm", "Cm", "C#m", "Dm", "D#m", "Em", "Fm", "F#m","Gm", "G#m"]
# Fungsi untuk memasukkan nada ke partitur pada posisi tertentu
def insert_note(note):
current_content = output_text.get("1.0", tk.INSERT)
lines = current_content.split("\n")
# Cari baris terakhir birama
last_birama_line_index = None
for i, line in enumerate(reversed(lines)):
if "|" in line: # Cek untuk birama
last_birama_line_index = len(lines) - i - 1
break
# Pindah ke baris baru jika nada terlalu panjang untuk satu birama
if last_birama_line_index is not None:
if len(lines[last_birama_line_index]) + len(note) > 30: # Contoh batas maksimal birama
output_text.insert(tk.INSERT, f"\n{create_birama_template()}|\nLirik: \n\n")
output_text.insert(tk.INSERT, note)
# Fungsi untuk membuat template birama
def create_birama_template():
template = "| | | | | | | | | | | | | | | | | | | |" # Garis birama 4/4
return template
# Fungsi untuk menambahkan birama ke output_text dengan pembatas di akhir
def add_birama():
birama = create_birama_template()
output_text.insert(tk.END, f"{birama}|\n") # Baris pertama: birama untuk nada (dengan pembatas di akhir)
output_text.insert(tk.END, "Lirik: " + " " * (len(birama) - 7) + "|\n") # Baris kedua: tempat lirik (dengan pembatas di akhir)
output_text.insert(tk.END, "\n") # Baris ketiga: separator kosong untuk jarak antar birama
# Membuat canvas untuk konten partitur
output_text_canvas = tk.Canvas(root, width=800, height=600)
output_text_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# Scrollbars untuk canvas
scrollbar_y = tk.Scrollbar(root, orient=tk.VERTICAL, command=output_text_canvas.yview)
scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
scrollbar_x = tk.Scrollbar(root, orient=tk.HORIZONTAL, command=output_text_canvas.xview)
scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
# Configure scrolling
output_text_canvas.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
output_text_canvas.bind('<Configure>', lambda e: output_text_canvas.configure(scrollregion=output_text_canvas.bbox('all')))
# Membuat frame untuk konten di dalam canvas
output_frame = tk.Frame(output_text_canvas)
output_text_canvas.create_window((0, 0), window=output_frame, anchor="nw")
# Membuat kotak untuk tombol simbol notasi
symbol_frame = tk.Frame(output_frame)
symbol_frame.grid(row=0, column=0, pady=5)
# Label instruksi simbol
symbol_label = tk.Label(symbol_frame, text="Simbol Notasi Angka:")
symbol_label.grid(row=0, column=0, columnspan=6, pady=(0, 5))
# Loop untuk membuat tombol untuk setiap simbol
for i, symbol in enumerate(symbol_options):
button = tk.Button(symbol_frame, text=symbol, width=2, command=lambda s=symbol: insert_symbol(s))
button.grid(row=1 + i // 8, column=i % 8, padx=5, pady=5)
# Frame untuk dropdown akord
chord_frame = tk.Frame(output_frame)
chord_frame.grid(row=1, column=0, pady=5)
# Entry Nada Dasar (Dropdown)
nada_dasar_label = tk.Label(chord_frame, text="Nada Dasar Lagu :")
nada_dasar_label.grid(row=0, column=0, padx=1, pady=5)
# Dropdown untuk Mayor/Minor
Mayor_minor_dropdown = ttk.Combobox(chord_frame, values=["Mayor", "minor"], state="readonly")
Mayor_minor_dropdown.grid(row=0, column=1, padx=(1, 2), pady=5)
Mayor_minor_dropdown.set("Mayor") # Default ke "Mayor"
do_label = tk.Label(chord_frame, text="1 == ", width=4, anchor="e", font=("Helvetica", 11, "bold"))
do_label.grid(row=0, column=2, padx=(0, 1), pady=5, sticky="e") # Kurangi padding kiri ke 0
# Dropdown untuk Nilai Nada Dasar
nada_dasar_dropdown = ttk.Combobox(chord_frame, values=nada_dasar, state="readonly")
nada_dasar_dropdown.grid(row=0, column=3, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
nada_dasar_dropdown.set("C") # Default Nada Dasar diatur ke "C"
# Tombol untuk menampilkan akord
button_tampilkan_akord = tk.Button(chord_frame, text="Tampilkan Akord", bg="grey", fg="white", command=tampilkan_akord)
button_tampilkan_akord.grid(row=1, column=0, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
# Combobox untuk pilihan akord
akord_label = tk.Label(chord_frame, justify="right", text="Pilih Akord Nada : ")
akord_label.grid(row=1, column=1, padx=(1, 2), pady=5, sticky="e") # Kurangi padding kanan ke 1
combobox_akord = ttk.Combobox(chord_frame, state="readonly")
combobox_akord.grid(row=1, column=2, padx=(1, 2), pady=5) # Kurangi padding kanan ke 1
combobox_akord.bind("<<ComboboxSelected>>", insert_selected_akord)
# Fungsi untuk menampilkan partitur dengan indentasi
def show_partitur():
output_text.delete(1.0, tk.END)
output_text.insert(tk.END, "\nPartitur Notasi Angka :\n", "indent")
output_text.insert(tk.END, f"Judul Lagu : \n", "indent")
output_text.insert(tk.END, f"Nada Dasar : \n", "indent")
output_text.insert(tk.END, f"Tanda Birama : \n", "indent")
output_text.insert(tk.END, f"Pencipta : \n", "indent")
output_text.insert(tk.END, f"Arranger : \n", "indent")
output_text.insert(tk.END, "\nArah/Arus Musik :\n", "indent")
output_text.insert(tk.END, "Tempo (BPM) :\n", "indent")
output_text.insert(tk.END, " \n \n", "indent")
output_text.insert(tk.END, create_birama_template() + "\n")
output_text.insert(tk.END, "Lirik: " + " " * (len(create_birama_template()) - 7) + "|\n\n") # Baris kedua: tempat lirik (dengan pembatas di akhir)
output_text.insert(tk.END, "\n") # Baris ketiga: separator kosong untuk jarak antar birama
# Menonaktifkan tombol setelah ditekan
show_partitur_button.config(state=tk.DISABLED, bg="lightgrey", text="Tombol Tidak Aktif")
# Fungsi untuk mengaktifkan kembali tombol Tampil Partitur
def reset_button():
show_button.config(state=tk.NORMAL, bg="grey", text="Tampilkan Partitur")
# Fungsi untuk menyimpan perubahan
def save_partitur():
edited_text = output_text.get(1.0, tk.END).strip()
file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text Files", "*.txt")])
if file_path:
try:
with open(file_path, 'w') as file:
file.write(edited_text)
messagebox.showinfo("Sukses", "Partitur berhasil disimpan.")
except Exception as e:
messagebox.showerror("Error", f"Gagal menyimpan partitur: {e}")
# Fungsi untuk membuka file partitur
def open_partitur():
file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt"), ("All files", "*.*")])
if file_path:
with open(file_path, "r") as file:
content = file.read()
output_text.delete(1.0, tk.END)
output_text.insert(tk.END, content)
# Tombol untuk menampilkan partitur
show_partitur_button = tk.Button(output_frame, text="Tampilkan Partitur", bg="grey", fg="white", command=show_partitur)
show_partitur_button.grid(row=7, column=0, padx=(1, 2), pady=5)
# Tombol untuk mengaktifkan kembali tombol Tampil Partitur
reset_button = tk.Button(output_frame, text="Reset", bg="blue", fg="white", command=reset_button)
reset_button.grid(row=7, column=1, padx=5, pady=5)
# Fungsi untuk memasukkan nada ke partitur di posisi kursor
def paste_gn():
try:
with open("temp_gn_value.txt", "r") as temp_file:
gn_value = temp_file.read()
current_index = output_text.index(tk.INSERT)
output_text.insert(current_index, gn_value)
except FileNotFoundError:
output_text.insert(tk.INSERT, "Tidak ada data yang dicopy.")
# Tombol untuk mem-paste gugus nada ke output_text
paste_gn_button = tk.Button(output_frame, text="Paste Gn", bg="green", fg="white", command=paste_gn)
paste_gn_button.grid(row=8, column=0, padx=5, pady=5)
# Tombol untuk menyimpan partitur
save_button = tk.Button(output_frame, text="Simpan Partitur", bg="grey", fg="white", command=save_partitur)
save_button.grid(row=7, column=2, padx=5, pady=5)
# Tombol untuk membuka partitur
open_button = tk.Button(output_frame, text="Buka Partitur", bg="grey", fg="white",command=open_partitur)
open_button.grid(row=7, column=3, padx=5, pady=5)
# Tombol untuk menambahkan birama
add_birama_button = tk.Button(output_frame, text="Tambah Birama", bg="grey", fg="white", command=add_birama)
add_birama_button.grid(row=8, column=1, padx=5, pady=5)
# Label instruksi di atas output_text
instruksi_label = tk.Label(output_frame, text="Partitur Notasi Angka (Edit di bawah sini):")
instruksi_label.grid(row=9, column=0, padx=5, pady=5)
# Membuat Text Widget untuk output
output_text = tk.Text(output_frame, wrap=tk.WORD, undo=True, width=80, height=50, font=("Courier", 10))
output_text.grid(row=10, column=0, columnspan=3, padx=10, pady=10)
# Menambahkan Scrollbars ke Text Widget
output_text_scrollbar_y = tk.Scrollbar(output_frame, orient=tk.VERTICAL, command=output_text.yview)
output_text_scrollbar_y.grid(row=9, column=3, sticky="ns")
output_text.configure(yscrollcommand=output_text_scrollbar_y.set)
output_text_scrollbar_x = tk.Scrollbar(output_frame, orient=tk.HORIZONTAL, command=output_text.xview)
output_text_scrollbar_x.grid(row=20, column=0, columnspan=3, sticky="we")
output_text.configure(xscrollcommand=output_text_scrollbar_x.set)
# Menambah gaya (style) pada text untuk superscript
output_text.tag_configure("superscript", offset=-5) # Gunakan offset negatif untuk superscript
output_text.tag_configure("chord_color", foreground="blue")
# Fungsi untuk memasukkan akord ke partitur, di posisi superscript
def insert_chord(chord):
global line_count
# Tambahkan chord dalam mode superscript
output_text.insert(tk.INSERT, chord, ("superscript", "chord_color"))
# Jika mencapai batas baris untuk satu halaman, tambahkan pembatas
line_count += 1
if line_count % 50 == 0:
add_page_separator()
# Fungsi untuk menambahkan pembatas antar halaman
def add_page_separator():
output_text.insert(tk.END, "\n" + "-" * 50 + " Halaman Baru " + "-" * 50 + "\n")
# Fungsi untuk menyimpan sementara gugus nada ke dalam file sementara
def copy_gn():
try:
selected_text = output_text.get(tk.SEL_FIRST, tk.SEL_LAST)
with open("temp_gn_value.txt", "w") as temp_file:
temp_file.write(selected_text)
messagebox.showinfo("Sukses", "Gugus Nada berhasil disalin.")
except tk.TclError:
messagebox.showwarning("Peringatan", "Tidak ada teks yang disalin.")
# Tombol untuk menyalin gugus nada ke file sementara
copy_gn_button = tk.Button(output_frame, text="Salin Gn", bg="grey", fg="white", command=copy_gn)
copy_gn_button.grid(row=8, column=2, padx=5, pady=5)
# Fungsi untuk keluar dari aplikasi
def exit_app():
result = messagebox.askquestion("Keluar", "Apakah Anda yakin ingin keluar?", icon="warning")
if result == 'yes':
root.quit()
# Tombol untuk keluar dari aplikasi
exit_button = tk.Button(output_frame, text="Keluar", bg="red", fg="white", command=exit_app)
exit_button.grid(row=11, column=3, padx=10, pady=10)
# Frame untuk tombol navigasi halaman dan konten
page_navigation_frame = tk.Frame(output_frame)
page_navigation_frame.grid(row=2, column=0, pady=5)
# List halaman untuk konten
pages = [
"Ini adalah halaman 1\n",
"Ini adalah halaman 2\n",
"Ini adalah halaman 3\n",
"Ini adalah halaman 4\n",
"Ini adalah halaman 5\n",
]
current_page = 0
# Fungsi untuk update halaman
def update_page():
output_text.delete(1.0, tk.END)
output_text.insert(tk.END, pages[current_page])
def show_previous_page():
global current_page
if current_page > 0:
current_page -= 1
update_page()
def show_next_page():
global current_page
if current_page < len(pages) - 1:
current_page += 1
update_page()
# Tombol Previous
prev_button = tk.Button(output_frame, text="Previous", bg="lightgreen", fg="red", command=show_previous_page)
prev_button.grid(row=11, column=0, padx=10)
# Tombol Next
next_button = tk.Button(output_frame, text="Next", bg="lightgreen", fg="red", command=show_next_page)
next_button.grid(row=11, column=1, padx=10)
# Memasukkan halaman pertama saat dimulai
update_page()
# Fungsi utama untuk menjalankan aplikasi
def main():
root.mainloop()
# Memanggil fungsi utama
if __name__ == "__main__":
main()
Komentar
Posting Komentar
This Message