Začetna verzija (avtor U. Urbanija)
This commit is contained in:
417
add_song.py
Normal file
417
add_song.py
Normal file
@@ -0,0 +1,417 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sqlite3
|
||||
import json
|
||||
import os
|
||||
|
||||
DB_PATH = 'songs.db'
|
||||
SETTINGS_PATH = 'settings.json'
|
||||
EXPORT_PATH = 'pesmi_export.txt'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# PREDHODNE NASTAVITVE IN POVEZAVA NA BAZO
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
if not os.path.exists(SETTINGS_PATH):
|
||||
print("Nastavitve manjkajo! Zaženi 'nastavitve.bat' najprej.")
|
||||
exit()
|
||||
|
||||
with open(SETTINGS_PATH, "r", encoding="utf-8") as f:
|
||||
settings = json.load(f)
|
||||
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS songs (
|
||||
id INTEGER PRIMARY KEY,
|
||||
title TEXT,
|
||||
lyrics TEXT
|
||||
)''')
|
||||
conn.commit()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# POMOŽNE FUNKCIJE
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def get_next_free_id(start: int = 792) -> int:
|
||||
"""Vrne prvo prosto številko pesmi, ki je ≥ start (privzeto 792)."""
|
||||
next_id = start
|
||||
while True:
|
||||
cursor.execute("SELECT 1 FROM songs WHERE id = ?", (next_id,))
|
||||
if cursor.fetchone() is None:
|
||||
return next_id
|
||||
next_id += 1
|
||||
|
||||
def slovenski_kljuc(naslov: str) -> str:
|
||||
nadom = {'č': 'cz', 'Č': 'Cz', 'š': 'sz', 'Š': 'Sz', 'ž': 'zz', 'Ž': 'Zz'}
|
||||
return ''.join(nadom.get(z, z) for z in naslov).lower()
|
||||
|
||||
def prikazi_meni():
|
||||
print("\nIzberi možnost:")
|
||||
print("1. Dodaj pesem")
|
||||
print("2. Uredi pesem")
|
||||
print("3. Prestavi pesem")
|
||||
print("4. Izbriši pesem")
|
||||
print("5. Izvozi bazo v TXT")
|
||||
print("6. Uvozi bazo iz TXT")
|
||||
print("7. Izpiši kazalo")
|
||||
print("8. Zaženi projekcijo")
|
||||
print("9. Zapri program")
|
||||
|
||||
def uredi_vnos(lines):
|
||||
processed, prazne = [], 0
|
||||
for line in lines:
|
||||
if line.strip() == "":
|
||||
prazne += 1
|
||||
continue
|
||||
if prazne:
|
||||
processed.extend([""] * prazne)
|
||||
prazne = 0
|
||||
if line.strip().startswith("- "):
|
||||
line = line.replace("- ", "• ", 1)
|
||||
processed.append(line)
|
||||
if prazne:
|
||||
processed.extend([""] * prazne)
|
||||
return "\n".join(processed)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# FUNKCIJE POSAMEZNIH MENIJSKIH OPCIJ
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def dodaj_pesem():
|
||||
# -- izbira št. pesmi ----------------------------------------------------
|
||||
while True:
|
||||
try:
|
||||
song_id = int(input("Vnesi številko pesmi: "))
|
||||
break
|
||||
except ValueError:
|
||||
print("Vnesi veljavno celo število!")
|
||||
|
||||
cursor.execute("SELECT title FROM songs WHERE id = ?", (song_id,))
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
print(f"Želiš prepisati obstoječo pesem {song_id} – {row[0]}?")
|
||||
predlagana = get_next_free_id()
|
||||
print(f"Prva prosta številka nad 791 je {predlagana}.")
|
||||
izbira = input("D = prepiši, N ali Enter = uporabi predlagano, "
|
||||
"ali vnesi drugo številko: ").strip()
|
||||
|
||||
if izbira.lower() == "d":
|
||||
pass
|
||||
elif izbira.lower() == "n" or izbira == "":
|
||||
song_id = predlagana
|
||||
else:
|
||||
try:
|
||||
song_id = int(izbira)
|
||||
except ValueError:
|
||||
print("Neveljaven vnos – uporabljam predlagano številko.")
|
||||
song_id = predlagana
|
||||
|
||||
# -- vnos besedila -------------------------------------------------------
|
||||
title = input("Vnesi naslov pesmi: ")
|
||||
print("Vnesi besedilo (prazna vrstica = presledek, dve prazni = nova kitica).\n"
|
||||
"Ko končaš, vpiši 'konec'.")
|
||||
|
||||
lines = []
|
||||
while True:
|
||||
line = input()
|
||||
if line.strip().lower() == "konec":
|
||||
break
|
||||
if line.strip().startswith("- "):
|
||||
line = line.replace("- ", "• ", 1)
|
||||
lines.append(line)
|
||||
|
||||
full_lyrics = uredi_vnos(lines)
|
||||
cursor.execute("INSERT OR REPLACE INTO songs (id, title, lyrics) VALUES (?,?,?)",
|
||||
(song_id, title, full_lyrics))
|
||||
conn.commit()
|
||||
print("Pesem uspešno shranjena!")
|
||||
|
||||
def uredi_pesem():
|
||||
try:
|
||||
song_id = int(input("Vnesi številko pesmi za urejanje: "))
|
||||
except ValueError:
|
||||
print("Uporabi celo število!")
|
||||
return
|
||||
|
||||
cursor.execute("SELECT title, lyrics FROM songs WHERE id = ?", (song_id,))
|
||||
result = cursor.fetchone()
|
||||
if not result:
|
||||
print("Pesem s to številko ne obstaja.")
|
||||
return
|
||||
|
||||
print(f"Trenutni naslov: {result[0]}")
|
||||
print(f"Trenutno besedilo:\n{result[1]}")
|
||||
|
||||
new_title = input("Nov naslov (pusti prazno za obdržanje): ")
|
||||
print("Novo besedilo (vpiši 'konec' za zaključek, pusti prazno za obdržanje):")
|
||||
|
||||
lines = []
|
||||
while True:
|
||||
line = input()
|
||||
if line.strip().lower() == "konec":
|
||||
break
|
||||
if line.strip().startswith("- "):
|
||||
line = line.replace("- ", "• ", 1)
|
||||
lines.append(line)
|
||||
|
||||
if new_title.strip() == "":
|
||||
new_title = result[0]
|
||||
new_lyrics = result[1] if len(lines) == 0 else uredi_vnos(lines)
|
||||
|
||||
cursor.execute("UPDATE songs SET title = ?, lyrics = ? WHERE id = ?",
|
||||
(new_title, new_lyrics, song_id))
|
||||
conn.commit()
|
||||
print("Pesem uspešno posodobljena!")
|
||||
|
||||
def prestavi_pesem():
|
||||
try:
|
||||
old_id = int(input("Vnesi številko pesmi, ki jo želiš prestaviti: "))
|
||||
new_id = int(input("Vnesi novo številko pesmi: "))
|
||||
except ValueError:
|
||||
print("Uporabi cela števila!")
|
||||
return
|
||||
|
||||
cursor.execute("SELECT title, lyrics FROM songs WHERE id = ?", (old_id,))
|
||||
vir = cursor.fetchone()
|
||||
if vir is None:
|
||||
print("Pesem s to številko ne obstaja.")
|
||||
return
|
||||
|
||||
cursor.execute("SELECT title FROM songs WHERE id = ?", (new_id,))
|
||||
cilj = cursor.fetchone()
|
||||
if cilj:
|
||||
print(f"Želiš prepisati obstoječo pesem {new_id} – {cilj[0]}?")
|
||||
predlagana = get_next_free_id()
|
||||
print(f"Prva prosta številka nad 791 je {predlagana}.")
|
||||
izbira = input("D = prepiši, N ali Enter = predlagana, ali vnesi drugo številko: ").strip()
|
||||
if izbira.lower() == "d":
|
||||
pass
|
||||
elif izbira.lower() == "n" or izbira == "":
|
||||
new_id = predlagana
|
||||
else:
|
||||
try:
|
||||
new_id = int(izbira)
|
||||
except ValueError:
|
||||
print("Neveljaven vnos – uporabljam predlagano številko.")
|
||||
new_id = predlagana
|
||||
|
||||
cursor.execute("INSERT OR REPLACE INTO songs (id, title, lyrics) VALUES (?,?,?)",
|
||||
(new_id, vir[0], vir[1]))
|
||||
cursor.execute("DELETE FROM songs WHERE id = ?", (old_id,))
|
||||
conn.commit()
|
||||
print("Pesem uspešno prestavljena!")
|
||||
|
||||
def izbrisi_pesem():
|
||||
try:
|
||||
song_id = int(input("Vnesi številko pesmi za izbris: "))
|
||||
except ValueError:
|
||||
print("Uporabi celo število!")
|
||||
return
|
||||
|
||||
cursor.execute("SELECT title FROM songs WHERE id = ?", (song_id,))
|
||||
row = cursor.fetchone()
|
||||
if row is None:
|
||||
print("Pesem s to številko ne obstaja.")
|
||||
return
|
||||
|
||||
potrdi = input(f"Želiš res izbrisati pesem {song_id} – {row[0]}? (D/N): ").strip().lower()
|
||||
if potrdi == "d":
|
||||
cursor.execute("DELETE FROM songs WHERE id = ?", (song_id,))
|
||||
conn.commit()
|
||||
print("Pesem uspešno izbrisana!")
|
||||
else:
|
||||
print("Brisanje preklicano.")
|
||||
|
||||
def izvozi_bazo():
|
||||
cursor.execute("SELECT id, title, lyrics FROM songs ORDER BY id")
|
||||
pesmi = cursor.fetchall()
|
||||
with open(EXPORT_PATH, "w", encoding="utf-8") as f:
|
||||
for pesem in pesmi:
|
||||
f.write("===\n")
|
||||
f.write(f"{pesem[0]}\n{pesem[1]}\n{pesem[2]}\n")
|
||||
print(f"Baza je bila izvožena v '{EXPORT_PATH}'.")
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 6. UVOZ BAZE Z NAPREDNO KONTROLO PODVOJENIH PESMI
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def uvozi_bazo():
|
||||
if not os.path.exists(EXPORT_PATH):
|
||||
print(f"Datoteka '{EXPORT_PATH}' ne obstaja.")
|
||||
return
|
||||
|
||||
with open(EXPORT_PATH, "r", encoding="utf-8") as f:
|
||||
vsebina = f.read().replace('\r\n', '\n').replace('\r', '\n')
|
||||
|
||||
pesmi_raw = [p for p in vsebina.strip().split("===\n") if p.strip()]
|
||||
|
||||
duplicate_mode = None # 'd', 'n', 'p' ==> vedno prepiši / preskoči / nova ID
|
||||
|
||||
for pesem_raw in pesmi_raw:
|
||||
vrstice = pesem_raw.strip().split("\n")
|
||||
if len(vrstice) < 3:
|
||||
print("Preskočena nepopolna pesem.")
|
||||
continue
|
||||
|
||||
try:
|
||||
song_id = int(vrstice[0])
|
||||
except ValueError:
|
||||
print("Neveljaven ID – preskočeno.")
|
||||
continue
|
||||
|
||||
title = vrstice[1]
|
||||
raw_lyrics_lines = vrstice[2:]
|
||||
|
||||
# -- predobdelava besedila ------------------------------------------
|
||||
processed_lines, prazne = [], 0
|
||||
for line in raw_lyrics_lines:
|
||||
if line.strip().startswith("- "):
|
||||
line = line.replace("- ", "• ", 1)
|
||||
if line.strip() == "":
|
||||
prazne += 1
|
||||
continue
|
||||
if prazne:
|
||||
processed_lines.extend([""] * prazne)
|
||||
prazne = 0
|
||||
processed_lines.append(line)
|
||||
if prazne:
|
||||
processed_lines.extend([""] * prazne)
|
||||
|
||||
lyrics = "\n".join(processed_lines)
|
||||
|
||||
# -- obravnava podvojene številke -----------------------------------
|
||||
cursor.execute("SELECT title FROM songs WHERE id = ?", (song_id,))
|
||||
exists = cursor.fetchone()
|
||||
|
||||
if exists:
|
||||
# Če imamo globalni način, ga upoštevamo
|
||||
if duplicate_mode is not None:
|
||||
choice = duplicate_mode
|
||||
else:
|
||||
print(f"\nPozor: pesem št. {song_id} – \"{exists[0]}\" že obstaja.")
|
||||
print("Izberi dejanje:")
|
||||
print(" d … prepiši")
|
||||
print(" n … preskoči")
|
||||
print(" p … shrani pod prvo prosto številko ≥ 792")
|
||||
print(" da … prepiši to in vse naslednje podvojene pesmi")
|
||||
print(" na … preskoči to in vse naslednje podvojene pesmi")
|
||||
print(" pa … shrani to in vse naslednje podvojene pesmi pod novo ID")
|
||||
izbira = input("Tvoja izbira: ").strip().lower()
|
||||
|
||||
if izbira in {"da", "na", "pa"}:
|
||||
duplicate_mode = izbira[0] # 'd', 'n', 'p'
|
||||
choice = duplicate_mode
|
||||
elif izbira in {"d", "n", "p"}:
|
||||
choice = izbira
|
||||
else:
|
||||
print("Neznana izbira – pesem preskočena.")
|
||||
continue
|
||||
|
||||
# izvajanje po izbrani logiki
|
||||
if choice == "n":
|
||||
print("Pesem preskočena.")
|
||||
continue
|
||||
elif choice == "p":
|
||||
song_id = get_next_free_id()
|
||||
print(f"Shranjujem pod novo številko {song_id}.")
|
||||
# choice == 'd' -> prepis
|
||||
|
||||
# -- shranjevanje pesmi ---------------------------------------------
|
||||
cursor.execute("INSERT OR REPLACE INTO songs (id, title, lyrics) VALUES (?,?,?)",
|
||||
(song_id, title, lyrics))
|
||||
|
||||
conn.commit()
|
||||
print("\nUvoz pesmi uspešen!")
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# DODATNE FUNKCIJE (kazalo, projekcija) – nespremenjene
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def izpisi_kazalo():
|
||||
poglavja = [
|
||||
(13, " -- SLAVIMO GOSPODA -- "),
|
||||
(13, "ADVENTNE"),
|
||||
(27, "BOŽIČNA DEVETDNEVNICA"),
|
||||
(39, "BOŽIČNE"),
|
||||
(65, "POSTNE"),
|
||||
(119, "VELIKONOČNE"),
|
||||
(142, "ČAS MED LETOM"),
|
||||
(160, "MARIJINE"),
|
||||
(240, "SVETNIŠKE"),
|
||||
(263, "ZAKRAMENTI"),
|
||||
(383, "MAŠNE"),
|
||||
(406, "DAROVANJSKE"),
|
||||
(419, "OBHAJILNE"),
|
||||
(470, "BLAGOSLOVNE"),
|
||||
(497, "ZAKRAMENT SPRAVE"),
|
||||
(505, "MAŠNIŠKO POSVEČENJE"),
|
||||
(539, "POGREB"),
|
||||
(696, "LITANIJE"),
|
||||
(773, "KRIŽEV POT"),
|
||||
(777, "ROŽNI VENEC"),
|
||||
(786, "MISIJONSKE"),
|
||||
(788, "ZAHVALNE"),
|
||||
(790, "JUBILATE DEO in ON ŽIVI"),
|
||||
(1273,"DRUGE PESMI"),
|
||||
]
|
||||
|
||||
cursor.execute("SELECT id, title FROM songs ORDER BY id")
|
||||
zaporedno = cursor.fetchall()
|
||||
|
||||
cursor.execute("SELECT id, title FROM songs")
|
||||
abecedno = cursor.fetchall()
|
||||
abecedno.sort(key=lambda x: slovenski_kljuc(x[1]))
|
||||
|
||||
with open("kazalo.txt", "w", encoding="utf-8") as f:
|
||||
f.write("ZAPOREDNO KAZALO\n")
|
||||
trenutno_poglavje, indeks = None, 0
|
||||
|
||||
for pesem in zaporedno:
|
||||
while indeks < len(poglavja) and pesem[0] >= poglavja[indeks][0]:
|
||||
trenutno_poglavje = poglavja[indeks][1]
|
||||
f.write(f"\n--- {trenutno_poglavje} ---\n")
|
||||
indeks += 1
|
||||
f.write(f"{pesem[0]}\t{pesem[1]}\n")
|
||||
|
||||
f.write("\n\nABECEDNO KAZALO\n")
|
||||
for pesem in abecedno:
|
||||
f.write(f"{pesem[0]}\t{pesem[1]}\n")
|
||||
|
||||
print("Kazalo izpisano v 'kazalo.txt'.")
|
||||
|
||||
def zazeni_projekcijo():
|
||||
print("Zaganjam projekcijo …")
|
||||
conn.close()
|
||||
python_exe = os.sys.executable
|
||||
os.execl(python_exe, python_exe, "projector.py")
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# G L A V N I Z A G O N
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def main():
|
||||
while True:
|
||||
prikazi_meni()
|
||||
izbira = input("Vnesi številko možnosti: ").strip()
|
||||
os.system('cls' if os.name == 'nt' else 'clear')
|
||||
|
||||
if izbira == "1": dodaj_pesem()
|
||||
elif izbira == "2": uredi_pesem()
|
||||
elif izbira == "3": prestavi_pesem()
|
||||
elif izbira == "4": izbrisi_pesem()
|
||||
elif izbira == "5": izvozi_bazo()
|
||||
elif izbira == "6": uvozi_bazo()
|
||||
elif izbira == "7": izpisi_kazalo()
|
||||
elif izbira == "8": zazeni_projekcijo()
|
||||
elif izbira == "9":
|
||||
print("Program se zapira …")
|
||||
break
|
||||
else:
|
||||
print("Napačna izbira, poskusi znova.")
|
||||
|
||||
conn.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
377
nastavitve.py
Normal file
377
nastavitve.py
Normal file
@@ -0,0 +1,377 @@
|
||||
import tkinter as tk
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
DEFAULT_SETTINGS = {
|
||||
"font_name": "Times New Roman",
|
||||
"bg_color": "#000000",
|
||||
"fg_color": "#FFFFFF",
|
||||
"font_size": 32,
|
||||
"screen_width_percent": 60,
|
||||
"font_bold": True,
|
||||
"show_song_info": True,
|
||||
"split_by_stanza": True
|
||||
}
|
||||
|
||||
SETTINGS_FILE = "settings.json"
|
||||
|
||||
if not os.path.exists(SETTINGS_FILE):
|
||||
with open(SETTINGS_FILE, "w") as f:
|
||||
json.dump(DEFAULT_SETTINGS, f, indent=4)
|
||||
|
||||
def load_settings():
|
||||
with open(SETTINGS_FILE, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
def save_settings(settings):
|
||||
with open(SETTINGS_FILE, "w") as f:
|
||||
json.dump(settings, f, indent=4)
|
||||
|
||||
def run_menu():
|
||||
root = tk.Tk()
|
||||
root.attributes("-fullscreen", True)
|
||||
root.update_idletasks()
|
||||
|
||||
settings = load_settings()
|
||||
|
||||
def calculate_max_font_size():
|
||||
screen_height = root.winfo_screenheight()
|
||||
screen_width = root.winfo_screenwidth()
|
||||
max_lines = 12
|
||||
max_height_per_line = screen_height / max_lines
|
||||
max_font_size = int(max_height_per_line * 0.8)
|
||||
return min(max_font_size, settings["font_size"])
|
||||
|
||||
FONT_SIZE = calculate_max_font_size()
|
||||
FONT = (settings["font_name"], FONT_SIZE, "bold" if settings.get("font_bold") else "normal")
|
||||
|
||||
root.lift()
|
||||
root.attributes("-topmost", True)
|
||||
root.after(100, lambda: root.attributes("-topmost", False))
|
||||
root.configure(bg=settings["bg_color"])
|
||||
|
||||
screen_width = root.winfo_screenwidth()
|
||||
left_right_width = int((100 - settings["screen_width_percent"]) / 2 * screen_width / 100)
|
||||
|
||||
left_block = tk.Frame(root, bg="black", width=left_right_width)
|
||||
left_block.pack(side="left", fill="y")
|
||||
|
||||
right_block = tk.Frame(root, bg="black", width=left_right_width)
|
||||
right_block.pack(side="right", fill="y")
|
||||
|
||||
frame = tk.Frame(root, bg=settings["bg_color"])
|
||||
frame.pack(expand=True)
|
||||
|
||||
def restart_program():
|
||||
python = sys.executable
|
||||
subprocess.Popen([python] + sys.argv)
|
||||
sys.exit()
|
||||
|
||||
def update_menu(options, title, callback):
|
||||
for widget in frame.winfo_children():
|
||||
widget.destroy()
|
||||
|
||||
title_label = tk.Label(frame, text=title, font=FONT, fg=settings["fg_color"], bg=settings["bg_color"])
|
||||
title_label.pack(pady=(0, 20))
|
||||
|
||||
button_frame = tk.Frame(frame, bg=settings["bg_color"])
|
||||
button_frame.pack()
|
||||
|
||||
wrap_length = screen_width * settings["screen_width_percent"] // 100
|
||||
|
||||
for key, text in options.items():
|
||||
label = tk.Label(
|
||||
button_frame,
|
||||
text=f"{key}. {text}",
|
||||
anchor="w",
|
||||
font=FONT,
|
||||
fg=settings["fg_color"],
|
||||
bg=settings["bg_color"],
|
||||
wraplength=wrap_length
|
||||
)
|
||||
label.pack(fill='x', anchor="w")
|
||||
|
||||
entry = tk.Entry(frame, font=FONT, justify='center', fg=settings["fg_color"], bg=settings["bg_color"],
|
||||
insertbackground=settings["fg_color"])
|
||||
entry.pack(pady=20)
|
||||
|
||||
def on_enter(event=None):
|
||||
choice = entry.get()
|
||||
callback(choice)
|
||||
|
||||
entry.bind("<Return>", on_enter)
|
||||
root.after(100, entry.focus_set)
|
||||
|
||||
def keep_focus(entry_widget):
|
||||
def refocus():
|
||||
entry_widget.focus_set()
|
||||
entry_widget.after(1000, refocus)
|
||||
refocus()
|
||||
|
||||
keep_focus(entry)
|
||||
|
||||
def manual_input(prompt, setting_key):
|
||||
for widget in frame.winfo_children():
|
||||
widget.destroy()
|
||||
|
||||
label = tk.Label(frame, text=prompt, font=FONT, fg=settings["fg_color"], bg=settings["bg_color"])
|
||||
label.pack(pady=10)
|
||||
|
||||
entry = tk.Entry(frame, font=FONT, justify='center', fg=settings["fg_color"], bg=settings["bg_color"],
|
||||
insertbackground=settings["fg_color"])
|
||||
entry.pack(pady=20)
|
||||
|
||||
def on_enter(event=None):
|
||||
value = entry.get()
|
||||
if setting_key in ["font_size", "screen_width_percent"]:
|
||||
if value.isdigit():
|
||||
settings[setting_key] = int(value)
|
||||
else:
|
||||
settings[setting_key] = value
|
||||
save_settings(settings)
|
||||
restart_program()
|
||||
|
||||
entry.bind("<Return>", on_enter)
|
||||
root.after(100, entry.focus_set)
|
||||
|
||||
def keep_focus(entry_widget):
|
||||
def refocus():
|
||||
entry_widget.focus_set()
|
||||
entry_widget.after(1000, refocus)
|
||||
refocus()
|
||||
|
||||
keep_focus(entry)
|
||||
|
||||
def show_main_menu():
|
||||
options = {
|
||||
"1": "Spremeni pisavo",
|
||||
"2": "Spremeni barvo ozadja",
|
||||
"3": "Spremeni barvo črk",
|
||||
"4": "Spremeni barvo ozadja in črk",
|
||||
"5": "Spremeni velikost črk",
|
||||
"6": "Spremeni odebeljenost pisave",
|
||||
"7": "Prikaz številke in kitice",
|
||||
"8": "Prikaz samostojne kitice",
|
||||
"9": "Spremeni širino platna",
|
||||
"10": "Zaženi projekcijo",
|
||||
"11": "Zapri"
|
||||
}
|
||||
|
||||
def handle_main_choice(choice):
|
||||
if choice == "1":
|
||||
show_font_menu()
|
||||
elif choice == "2":
|
||||
show_bg_menu()
|
||||
elif choice == "3":
|
||||
show_fg_menu()
|
||||
elif choice == "4":
|
||||
show_bg_fg_combo_menu()
|
||||
elif choice == "5":
|
||||
manual_input("Vnesi velikost pisave (številka):", "font_size")
|
||||
elif choice == "6":
|
||||
toggle_bold_choice()
|
||||
elif choice == "7":
|
||||
toggle_show_song_info()
|
||||
elif choice == "8":
|
||||
toggle_split_by_stanza()
|
||||
elif choice == "9":
|
||||
manual_input("Vnesi širino platna (v %):", "screen_width_percent")
|
||||
elif choice == "10":
|
||||
root.destroy()
|
||||
subprocess.run(["python", "projector.py"])
|
||||
elif choice == "11":
|
||||
root.destroy()
|
||||
|
||||
update_menu(options, "Izberi možnost:", handle_main_choice)
|
||||
|
||||
def toggle_bold_choice():
|
||||
options = {
|
||||
"1": "Odebeljena pisava (Da)",
|
||||
"2": "Odebeljena pisava (Ne)"
|
||||
}
|
||||
|
||||
def handle_choice(choice):
|
||||
if choice == "1":
|
||||
settings["font_bold"] = True
|
||||
elif choice == "2":
|
||||
settings["font_bold"] = False
|
||||
save_settings(settings)
|
||||
restart_program()
|
||||
|
||||
update_menu(options, "Izberi možnost:", handle_choice)
|
||||
|
||||
def toggle_show_song_info():
|
||||
options = {
|
||||
"1": "Prikaz številke in kitice (Da)",
|
||||
"2": "Prikaz številke in kitice (Ne)"
|
||||
}
|
||||
|
||||
def handle_choice(choice):
|
||||
if choice == "1":
|
||||
settings["show_song_info"] = True
|
||||
elif choice == "2":
|
||||
settings["show_song_info"] = False
|
||||
save_settings(settings)
|
||||
restart_program()
|
||||
|
||||
update_menu(options, "Izberi možnost:", handle_choice)
|
||||
|
||||
def toggle_split_by_stanza():
|
||||
options = {
|
||||
"1": "Prelom po kiticah",
|
||||
"2": "Prelom ob polnem platnu"
|
||||
}
|
||||
|
||||
def handle_choice(choice):
|
||||
if choice == "1":
|
||||
settings["split_by_stanza"] = True
|
||||
elif choice == "2":
|
||||
settings["split_by_stanza"] = False
|
||||
save_settings(settings)
|
||||
restart_program()
|
||||
|
||||
update_menu(options, "Izberi način prikaza kitic:", handle_choice)
|
||||
|
||||
def show_font_menu():
|
||||
fonts = {
|
||||
"1": "Arial",
|
||||
"2": "Calibri",
|
||||
"3": "Times New Roman",
|
||||
"4": "Verdana",
|
||||
"5": "Georgia",
|
||||
"6": "Helvetica",
|
||||
"7": "Tahoma",
|
||||
"8": "Trebuchet MS",
|
||||
"9": "Courier New",
|
||||
"10": "Comic Sans MS"
|
||||
}
|
||||
|
||||
def set_font(choice):
|
||||
if choice in fonts:
|
||||
settings["font_name"] = fonts[choice]
|
||||
save_settings(settings)
|
||||
restart_program()
|
||||
|
||||
update_menu(fonts, "Izberi pisavo:", set_font)
|
||||
|
||||
def show_bg_menu():
|
||||
current_fg = settings["fg_color"]
|
||||
colors = {
|
||||
"1": "črna",
|
||||
"2": "bela",
|
||||
"3": "rdeča",
|
||||
"4": "zelena",
|
||||
"5": "modra",
|
||||
"6": "rumena",
|
||||
"7": "cian",
|
||||
"8": "magenta",
|
||||
"9": "siva",
|
||||
"10": "temno rdeča"
|
||||
}
|
||||
|
||||
color_values = {
|
||||
"črna": "#000000",
|
||||
"bela": "#FFFFFF",
|
||||
"rdeča": "#FF0000",
|
||||
"zelena": "#00FF00",
|
||||
"modra": "#0000FF",
|
||||
"rumena": "#FFFF00",
|
||||
"cian": "#00FFFF",
|
||||
"magenta": "#FF00FF",
|
||||
"siva": "#808080",
|
||||
"temno rdeča": "#800000"
|
||||
}
|
||||
|
||||
filtered_colors = {k: v for k, v in colors.items() if color_values.get(v, "") != current_fg}
|
||||
|
||||
def set_bg(choice):
|
||||
if choice in filtered_colors:
|
||||
settings["bg_color"] = color_values[filtered_colors[choice]]
|
||||
save_settings(settings)
|
||||
restart_program()
|
||||
|
||||
update_menu(filtered_colors, "Izberi barvo ozadja:", set_bg)
|
||||
|
||||
def show_fg_menu():
|
||||
current_bg = settings["bg_color"]
|
||||
colors = {
|
||||
"1": "bela",
|
||||
"2": "črna",
|
||||
"3": "rdeča",
|
||||
"4": "zelena",
|
||||
"5": "modra",
|
||||
"6": "rumena",
|
||||
"7": "cian",
|
||||
"8": "magenta",
|
||||
"9": "siva",
|
||||
"10": "temno rdeča"
|
||||
}
|
||||
|
||||
color_values = {
|
||||
"črna": "#000000",
|
||||
"bela": "#FFFFFF",
|
||||
"rdeča": "#FF0000",
|
||||
"zelena": "#00FF00",
|
||||
"modra": "#0000FF",
|
||||
"rumena": "#FFFF00",
|
||||
"cian": "#00FFFF",
|
||||
"magenta": "#FF00FF",
|
||||
"siva": "#808080",
|
||||
"temno rdeča": "#800000"
|
||||
}
|
||||
|
||||
filtered_colors = {k: v for k, v in colors.items() if color_values.get(v, "") != current_bg}
|
||||
|
||||
def set_fg(choice):
|
||||
if choice in filtered_colors:
|
||||
settings["fg_color"] = color_values[filtered_colors[choice]]
|
||||
save_settings(settings)
|
||||
restart_program()
|
||||
|
||||
update_menu(filtered_colors, "Izberi barvo črk:", set_fg)
|
||||
|
||||
def show_bg_fg_combo_menu():
|
||||
combinations = {
|
||||
"1": ("črna", "bela"),
|
||||
"2": ("bela", "črna"),
|
||||
"3": ("modra", "rumena"),
|
||||
"4": ("temno rdeča", "bela"),
|
||||
"5": ("zelena", "črna"),
|
||||
"6": ("rdeča", "črna"),
|
||||
"7": ("rumena", "črna"),
|
||||
"8": ("črna", "rumena"),
|
||||
"9": ("modra", "bela"),
|
||||
"10": ("siva", "črna"),
|
||||
}
|
||||
|
||||
color_values = {
|
||||
"črna": "#000000",
|
||||
"bela": "#FFFFFF",
|
||||
"rdeča": "#FF0000",
|
||||
"zelena": "#00FF00",
|
||||
"modra": "#0000FF",
|
||||
"rumena": "#FFFF00",
|
||||
"cian": "#00FFFF",
|
||||
"magenta": "#FF00FF",
|
||||
"siva": "#808080",
|
||||
"temno rdeča": "#800000"
|
||||
}
|
||||
|
||||
def handle_combo_choice(choice):
|
||||
if choice in combinations:
|
||||
bg_name, fg_name = combinations[choice]
|
||||
settings["bg_color"] = color_values[bg_name]
|
||||
settings["fg_color"] = color_values[fg_name]
|
||||
save_settings(settings)
|
||||
restart_program()
|
||||
|
||||
options = {key: f"{bg} ozadje / {fg} črke" for key, (bg, fg) in combinations.items()}
|
||||
update_menu(options, "Izberi kombinacijo barv:", handle_combo_choice)
|
||||
|
||||
show_main_menu()
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_menu()
|
||||
427
projector.py
Normal file
427
projector.py
Normal file
@@ -0,0 +1,427 @@
|
||||
import sqlite3
|
||||
import tkinter as tk
|
||||
import json
|
||||
import os
|
||||
import math
|
||||
import subprocess
|
||||
|
||||
DB_PATH = 'songs.db'
|
||||
SETTINGS_PATH = 'settings.json'
|
||||
|
||||
|
||||
class SongProjector:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.conn = sqlite3.connect(DB_PATH)
|
||||
self.cursor = self.conn.cursor()
|
||||
self.current_song = None
|
||||
self.pages = []
|
||||
self.current_page_index = 0
|
||||
self.song_number = ""
|
||||
self.song_number_last = ""
|
||||
self.all_caps_mode = False
|
||||
|
||||
# --------------------------------------------------
|
||||
# Nastavitve
|
||||
# --------------------------------------------------
|
||||
if not os.path.exists(SETTINGS_PATH):
|
||||
self.settings = {
|
||||
"font_name": "Times New Roman",
|
||||
"bg_color": "#000000",
|
||||
"fg_color": "#FFFFFF",
|
||||
"font_size": 32,
|
||||
"screen_width_percent": 60,
|
||||
"font_bold": True,
|
||||
"show_song_info": True
|
||||
}
|
||||
with open(SETTINGS_PATH, "w", encoding="utf-8") as f:
|
||||
json.dump(self.settings, f, indent=4)
|
||||
else:
|
||||
with open(SETTINGS_PATH, "r", encoding="utf-8") as f:
|
||||
self.settings = json.load(f)
|
||||
|
||||
self.line_height = int(int(self.settings["font_size"]) * 1.5)
|
||||
|
||||
# --------------------------------------------------
|
||||
# Okno
|
||||
# --------------------------------------------------
|
||||
root.attributes('-fullscreen', True)
|
||||
root.configure(bg=self.settings["bg_color"])
|
||||
root.bind("<Return>", self.enter_pressed)
|
||||
root.bind("<KP_Enter>", self.enter_pressed)
|
||||
root.bind("<plus>", self.clear_screen)
|
||||
root.bind("<minus>", self.prev_page)
|
||||
root.bind("<slash>", self.search_song)
|
||||
root.bind("<Key>", self.key_pressed)
|
||||
|
||||
screen_width = root.winfo_screenwidth()
|
||||
screen_height = root.winfo_screenheight()
|
||||
screen_width_percent = self.settings["screen_width_percent"]
|
||||
color_width = int(screen_width * screen_width_percent / 100)
|
||||
|
||||
self.screen_height = screen_height
|
||||
self.color_width = color_width
|
||||
|
||||
black_side_width = (screen_width - color_width) // 2
|
||||
|
||||
self.left_frame = tk.Frame(root, bg="black", width=black_side_width, height=screen_height)
|
||||
self.left_frame.pack(side="left", fill="y")
|
||||
|
||||
self.color_frame = tk.Frame(root, bg=self.settings["bg_color"], width=color_width, height=screen_height)
|
||||
self.color_frame.place(relx=0.5, rely=0.5, anchor="center")
|
||||
|
||||
self.right_frame = tk.Frame(root, bg="black", width=black_side_width, height=screen_height)
|
||||
self.right_frame.pack(side="right", fill="y")
|
||||
|
||||
font_weight = "bold" if self.settings.get("font_bold", False) else "normal"
|
||||
|
||||
self.label = tk.Label(
|
||||
self.color_frame,
|
||||
text="",
|
||||
bg=self.settings["bg_color"],
|
||||
fg=self.settings["fg_color"],
|
||||
font=(self.settings["font_name"], int(self.settings["font_size"]), font_weight),
|
||||
wraplength=color_width,
|
||||
justify="center"
|
||||
)
|
||||
self.label.pack(expand=True)
|
||||
|
||||
right_edge_x = int((screen_width - color_width) / 2 + color_width)
|
||||
|
||||
self.song_info_label = tk.Label(
|
||||
root,
|
||||
text="",
|
||||
bg=self.settings["bg_color"],
|
||||
fg=self.settings["fg_color"],
|
||||
font=(self.settings["font_name"], int(self.settings["font_size"]) - 5),
|
||||
anchor="se",
|
||||
justify="right"
|
||||
)
|
||||
self.song_info_label.place(x=right_edge_x - 10, y=screen_height - 10, anchor="se")
|
||||
|
||||
self.search_label = None
|
||||
self.search_entry = None
|
||||
self.waiting_for_song = True
|
||||
|
||||
# --------------------------------------------------
|
||||
# Samodejno skrivanje kazalca
|
||||
# --------------------------------------------------
|
||||
def hide_cursor_after_delay():
|
||||
self.root.config(cursor="none")
|
||||
|
||||
def reset_cursor_timer(event=None):
|
||||
self.root.config(cursor="")
|
||||
if hasattr(self, "cursor_job"):
|
||||
self.root.after_cancel(self.cursor_job)
|
||||
self.cursor_job = self.root.after(0, hide_cursor_after_delay)
|
||||
|
||||
self.root.bind_all('<Any-Motion>', reset_cursor_timer)
|
||||
self.root.bind_all('<Key>', reset_cursor_timer)
|
||||
self.cursor_job = self.root.after(0, hide_cursor_after_delay)
|
||||
|
||||
self.clear_screen()
|
||||
|
||||
# ------------------------------------------------------
|
||||
# NOVA METODA: enakomeren prelom predolgih vrstic
|
||||
# ------------------------------------------------------
|
||||
def split_long_line(self, line):
|
||||
"""
|
||||
Vrne seznam pod‑vrstic, ki skupaj tvorijo `line`,
|
||||
pri čemer so (približno) enako dolge glede na število znakov.
|
||||
"""
|
||||
avg_char_width = int(self.settings["font_size"]) * 0.57
|
||||
wraplength_px = self.color_width
|
||||
# Koliko znakov približno gre v eno vrstico
|
||||
approx_chars_per_line = max(1, int(wraplength_px / avg_char_width))
|
||||
|
||||
if len(line) <= approx_chars_per_line:
|
||||
return [line]
|
||||
|
||||
# Potrebno število pod‑vrstic
|
||||
n_sub = math.ceil(len(line) / approx_chars_per_line)
|
||||
|
||||
words = line.split()
|
||||
total_chars = sum(len(w) for w in words) + len(words) - 1 # vključno s presledki
|
||||
target_len = total_chars / n_sub
|
||||
|
||||
sub_lines = []
|
||||
current_words = []
|
||||
current_len = 0
|
||||
|
||||
for word in words:
|
||||
added_len = len(word) + (1 if current_words else 0) # presledek pred besedo, če ni prva
|
||||
if current_len + added_len > target_len and len(sub_lines) < n_sub - 1:
|
||||
# Začni novo vrstico
|
||||
sub_lines.append(" ".join(current_words))
|
||||
current_words = [word]
|
||||
current_len = len(word)
|
||||
else:
|
||||
current_words.append(word)
|
||||
current_len += added_len
|
||||
|
||||
if current_words:
|
||||
sub_lines.append(" ".join(current_words))
|
||||
|
||||
return sub_lines
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Upravljanje tipkovnice
|
||||
# ------------------------------------------------------
|
||||
def key_pressed(self, event):
|
||||
if event.keysym.isdigit():
|
||||
self.song_number += event.char
|
||||
elif event.keysym == "BackSpace":
|
||||
self.song_number = self.song_number[:-1]
|
||||
elif event.char == "*":
|
||||
self.all_caps_mode = not self.all_caps_mode
|
||||
self.show_page()
|
||||
|
||||
def enter_pressed(self, event=None):
|
||||
if self.song_number:
|
||||
self.load_song()
|
||||
elif not self.waiting_for_song:
|
||||
self.next_page()
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Nalaganje in obdelava pesmi
|
||||
# ------------------------------------------------------
|
||||
def load_song(self):
|
||||
if not self.song_number:
|
||||
return
|
||||
|
||||
if self.song_number == "0":
|
||||
self.clear_screen()
|
||||
self.song_number = ""
|
||||
return
|
||||
|
||||
# Ponastavitev izgleda barvnega območja
|
||||
self.color_frame.config(bg=self.settings["bg_color"], width=self.color_width, height=self.screen_height)
|
||||
self.color_frame.place(relx=0.5, rely=0.5, anchor="center")
|
||||
self.label.config(bg=self.settings["bg_color"], fg=self.settings["fg_color"])
|
||||
self.label.pack(expand=True)
|
||||
|
||||
# Posebni ukazi
|
||||
if self.song_number == "9999":
|
||||
subprocess.Popen(["shutdown", "/s", "/f", "/t", "0"])
|
||||
return
|
||||
elif self.song_number == "7777":
|
||||
subprocess.Popen(["python", "nastavitve.py"])
|
||||
self.exit_program()
|
||||
return
|
||||
elif self.song_number == "8888":
|
||||
self.exit_program()
|
||||
return
|
||||
elif self.song_number == "6666":
|
||||
subprocess.Popen(["python", "add_song.py"])
|
||||
self.exit_program()
|
||||
return
|
||||
|
||||
try:
|
||||
song_id = int(self.song_number)
|
||||
self.cursor.execute("SELECT lyrics FROM songs WHERE id=?", (song_id,))
|
||||
result = self.cursor.fetchone()
|
||||
if result:
|
||||
lyrics = result[0]
|
||||
|
||||
max_height = self.screen_height - (self.line_height * 1.5)
|
||||
avg_char_width = int(self.settings["font_size"]) * 0.57
|
||||
wraplength = self.color_width
|
||||
|
||||
# -------------------------------------------
|
||||
# 1. Razbijanje besedila na (pod-)vrstice
|
||||
# -------------------------------------------
|
||||
raw_lines = lyrics.strip().splitlines()
|
||||
processed_lines = []
|
||||
for raw in raw_lines:
|
||||
if raw.strip() == "":
|
||||
processed_lines.append("") # ohranimo prazno vrstico
|
||||
else:
|
||||
processed_lines.extend(self.split_long_line(raw))
|
||||
|
||||
# -------------------------------------------
|
||||
# 2. Razdeljevanje vrstic na strani
|
||||
# -------------------------------------------
|
||||
pages = []
|
||||
current_page_lines = []
|
||||
current_height = 0
|
||||
blank_line_count = 0
|
||||
|
||||
for line in processed_lines:
|
||||
is_blank = (line.strip() == "")
|
||||
if is_blank:
|
||||
blank_line_count += 1
|
||||
else:
|
||||
blank_line_count = 0
|
||||
|
||||
approx_line_length = len(line)
|
||||
approx_line_count = 1 if is_blank else math.ceil((approx_line_length * avg_char_width) / wraplength)
|
||||
needed_height = self.line_height * approx_line_count
|
||||
|
||||
# Prazna vrstica več kot 1‑krat pomeni nova kitica ⇒ nova stran
|
||||
if blank_line_count >= 2:
|
||||
if current_page_lines:
|
||||
pages.append("\n".join(current_page_lines).strip())
|
||||
current_page_lines = []
|
||||
current_height = 0
|
||||
blank_line_count = 0
|
||||
continue
|
||||
|
||||
# Če čez spodnji rob strani …
|
||||
if current_height + needed_height > max_height + self.line_height // 2:
|
||||
# poskusimo prelomiti na prazni vrstici znotraj strani
|
||||
found_split = False
|
||||
for i in reversed(range(len(current_page_lines))):
|
||||
if current_page_lines[i].strip() == "":
|
||||
pages.append("\n".join(current_page_lines[:i]).strip())
|
||||
current_page_lines = current_page_lines[i + 1:]
|
||||
current_height = sum(
|
||||
self.line_height * (
|
||||
1 if l.strip() == "" else math.ceil(len(l) * avg_char_width / wraplength)
|
||||
)
|
||||
for l in current_page_lines
|
||||
)
|
||||
found_split = True
|
||||
break
|
||||
if not found_split:
|
||||
pages.append("\n".join(current_page_lines).strip())
|
||||
current_page_lines = []
|
||||
current_height = 0
|
||||
|
||||
current_page_lines.append(line)
|
||||
current_height += needed_height
|
||||
|
||||
if current_page_lines:
|
||||
pages.append("\n".join(current_page_lines).strip())
|
||||
|
||||
self.pages = pages
|
||||
self.current_page_index = 0
|
||||
self.waiting_for_song = False
|
||||
self.song_number_last = self.song_number
|
||||
self.show_page()
|
||||
else:
|
||||
self.label.config(text="")
|
||||
self.pages = []
|
||||
self.current_page_index = 0
|
||||
self.waiting_for_song = True
|
||||
self.song_number_last = self.song_number
|
||||
self.song_info_label.config(text=self.song_number_last)
|
||||
self.song_info_label.lift()
|
||||
except Exception as e:
|
||||
self.label.config(text=f"Napaka: {e}")
|
||||
finally:
|
||||
self.song_number = ""
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Prikaz trenutne strani
|
||||
# ------------------------------------------------------
|
||||
def show_page(self):
|
||||
if self.pages:
|
||||
text = self.pages[self.current_page_index]
|
||||
if self.all_caps_mode:
|
||||
text = text.upper()
|
||||
self.label.config(text=text)
|
||||
if self.settings.get("show_song_info", False):
|
||||
current_page = self.current_page_index + 1
|
||||
total_pages = len(self.pages)
|
||||
self.song_info_label.config(text=f"{self.song_number_last} {current_page}/{total_pages}")
|
||||
self.song_info_label.lift()
|
||||
else:
|
||||
self.song_info_label.config(text="")
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Navigacija po straneh
|
||||
# ------------------------------------------------------
|
||||
def next_page(self, event=None):
|
||||
if self.pages and self.current_page_index + 1 < len(self.pages):
|
||||
self.current_page_index += 1
|
||||
self.show_page()
|
||||
|
||||
def prev_page(self, event=None):
|
||||
if self.pages and self.current_page_index > 0:
|
||||
self.current_page_index -= 1
|
||||
self.show_page()
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Očisti zaslon
|
||||
# ------------------------------------------------------
|
||||
def clear_screen(self, event=None):
|
||||
self.label.config(text="")
|
||||
self.label.pack_forget()
|
||||
self.color_frame.config(bg="black", width=self.color_width, height=self.screen_height)
|
||||
self.color_frame.place(relx=0.5, rely=0.5, anchor="center")
|
||||
self.song_info_label.config(text="")
|
||||
self.waiting_for_song = True
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Iskanje pesmi
|
||||
# ------------------------------------------------------
|
||||
def search_song(self, event=None):
|
||||
self.clear_screen()
|
||||
|
||||
if self.search_label:
|
||||
self.search_label.destroy()
|
||||
if self.search_entry:
|
||||
self.search_entry.destroy()
|
||||
|
||||
self.search_label = tk.Label(
|
||||
self.color_frame,
|
||||
text="Vpiši del naslova:",
|
||||
bg=self.settings["bg_color"],
|
||||
fg=self.settings["fg_color"],
|
||||
font=(self.settings["font_name"], int(self.settings["font_size"])),
|
||||
wraplength=self.color_width,
|
||||
justify="center"
|
||||
)
|
||||
self.search_label.pack(pady=(40, 10))
|
||||
|
||||
self.search_entry = tk.Entry(
|
||||
self.color_frame,
|
||||
font=(self.settings["font_name"], int(self.settings["font_size"])),
|
||||
justify="center",
|
||||
bg=self.settings["bg_color"],
|
||||
fg=self.settings["fg_color"],
|
||||
insertbackground=self.settings["fg_color"],
|
||||
borderwidth=0,
|
||||
highlightthickness=0
|
||||
)
|
||||
self.search_entry.pack()
|
||||
self.search_entry.focus()
|
||||
self.search_entry.bind("<Return>", self.perform_search)
|
||||
|
||||
def perform_search(self, event=None):
|
||||
query = self.search_entry.get().strip().lower()
|
||||
self.search_label.destroy()
|
||||
self.search_entry.destroy()
|
||||
|
||||
if query:
|
||||
self.cursor.execute("SELECT id, title FROM songs")
|
||||
all_results = self.cursor.fetchall()
|
||||
|
||||
matched = []
|
||||
for song_id, title in all_results:
|
||||
if query in title.lower():
|
||||
matched.append((song_id, title))
|
||||
|
||||
if matched:
|
||||
found = "\n".join(f"{id}: {title}" for id, title in matched)
|
||||
self.label.pack(expand=True)
|
||||
self.label.config(text=found)
|
||||
else:
|
||||
self.label.pack(expand=True)
|
||||
self.label.config(text="Ni zadetkov.")
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Izhod
|
||||
# ------------------------------------------------------
|
||||
def exit_program(self, event=None):
|
||||
self.conn.close()
|
||||
self.root.destroy()
|
||||
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Zagon aplikacije
|
||||
# ----------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
root = tk.Tk()
|
||||
app = SongProjector(root)
|
||||
root.mainloop()
|
||||
10
settings.json
Normal file
10
settings.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"font_name": "Times New Roman",
|
||||
"bg_color": "#000000",
|
||||
"fg_color": "#FFFFFF",
|
||||
"font_size": 38,
|
||||
"screen_width_percent": 60,
|
||||
"font_bold": true,
|
||||
"show_song_info": true,
|
||||
"split_by_stanza": true
|
||||
}
|
||||
Reference in New Issue
Block a user