Langsung ke konten utama

MEMBUAT TEMPLATE DAN KELENGKAPAN PARTITUR NOTASI ANGKA LAGU (Part-4)

 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

Postingan populer dari blog ini

Cara Download Aplikasi (.apk) Playstore Berbayar Jadi Gratis

  Langsung ke isi Menu Alutekno  »  Android  »  Cara Download Aplikasi (.apk) Playstore Berbayar Jadi Gratis Cara Download Aplikasi (.apk) Playstore Berbayar Jadi Gratis Download Aplikasi (Apk) Berbayar jadi Gratis di Playstore  – Pengguna smartphone Android semakin tahun semakin berkembang pesat begitu juga jumlah aplikasi yang telah di publish di playstore semakin meningkat pula. ADVERTISEMENT Daftar Isi Cara Download Aplikasi Playstore Berbayar Jadi Gratis 1. Download Aplikasi Blackmart Alpha 2. Menggunakan Lucky Patcher 3. Mencari File .apk Berbayar dari Situs File Sharing ADVERTISEMENT Aplikasi yang ada di playstore terbagi menjadi dua kategory yaitu yang gratis dan berbayar, aplikasi gratis biasanya terdapat iklan di dalamnya sehingga developer bisa mendapatkan uang untuk mengembangkan aplikasi yang telah di buatnya. Sedangkan Aplikasi berbayar atau premium biasanya tidak terdapat iklan dan mempunyai fitur yang lebih lengkap dibandingkan dengan aplika...

Cara Membuat Form Login Menggunakan HTML&CSS

  Upgrade Responses (2) Sukma Riadi Pakpahan What are your thoughts?  Cancel Respond Agustinus Giri Hartono 3 months ago Aku dah coba, tapi bagian bawah kotak login masih putih. Bagaimana supaya background sama dengan gradasi hijau? di >> body { background: -webkit-linear-gradient(bottom, #2dbd6e, #a6f77b); background-repeat: no-repeat; } 1 1 Arif Firmansyah 3 months ago terima kasih banyak boss cara menjelaskan sangat detail banget….saya berhasil membuat halaman login yang di jelaskan tadi, saya ingin penjelasannya lagi bagaimana cara masuk ke login dan membuat halaman baru karena saya masih pemula Welcome back. You are signed in as  srpakpahansst@gmail.com .  Not you? Tutorial Mendesain Form Login Menggunakan HTML&CSS Kimiyuki Yukawa Follow Mar 25, 2019  · 9 min read Tentu kita tidak asing lagi dengan istilah  login  dalam dunia  website . Halaman  login  sendiri dibuat untuk memberikan akses kepada  user...

PANDUAN CARA INSTALL WORDPRESS DI PC LOCALHOST [OFFLINE]

READY..! START BLOGGING WITH WORDPRESS..? Trending: 15+ Tema WordPress untuk... 15 Sumber Backlink Grati... Jual Tema WordPress Prem... Panduan Lengkap Cara Men... 5 Tema WordPress Terbaik... ALL ABOUT All About WORDPRESS Tutorial DESIGN All About THEMES Download LINUX Tutorial FOREX Forex DEALS Must See HOW TO START A BLOG? Panduan Membuat Blog Hanya 30 Menit Home  »  CMS  »  Panduan Cara Install WordPress di PC Localhost [Offline] PANDUAN CARA INSTALL WORDPRESS DI PC LOCALHOST [OFFLINE] Centerklik  |  CMS ,  WordPress Panduan Cara Install WordPress di PC Localhost [Offline]  – Jika Anda ingin memiliki blog gratis bisa membuat blog pada layanan gratis seperti blogger atau  membuat blog di WordPress.com . Keduanya memang gratis baik dari penggunaan domain maupun hosting, tapi tentunya sesuatu yang gratis tidak akan pernah di beri akses penuh dan masih banyak batasan, Dengan...